RedirectToAction called twice issue - asp.net-mvc

I have the controllers:
Controller A
{
public ActionResult ExecuteSomeStuff()
{
....use TempData
returns a View("StuffMade", SomeModel);
}
}
and
Controller B
{
public ActionResult DoStuff()
{
...fill up TempData
returns RedirectToAction("ExecuteSomeStuff", "A");
}
}
The problem is that the ExecuteSomeStuff method on controller A is executed twice.
I dont need the actual redirect to be made, I just want the result(the view) from the ExecuteSomeStuff method to be returned for DoStuff method.
I dont want to have a reference to controller A in controller B in order to call the method directly.
Is there any way to do this without the physical redirect or new reference to be made to controller A in controller B??

If I'm understanding you correctly, instead of a RedirectToAction, you can return the ExecuteSomeStuff View from Controller B. You will need to be able to set the Model to pass into the View from Controller B. So you may still need to make some reference to the methods used in Controller A.
Controller B:
{
public ActionResult DoStuff()
{
...fill up TempData
//set the model then Return the View with the Model passed in
return View("ExecuteSomeStuff","A",SomeModel);
}
UPDATE
This will look for a View with the same name as the action ExecuteSomeStuff without actually entering the ExecuteSomeStuff action. If your View has a different name, you can explicity specify the View to return like this:
return View("../A/theCorrectView.aspx", model);

Related

How can I send a parameter to partial view without the need of a model?

I have a partial view in my MVC app which I load into a container dom element. I do this by first calling the controller, like so:
$(container).load('/xxx/GetPartialView');
In the controller I return the partial view:
public PartialViewResult GetPartialView()
{
return PartialView("SomePartial", null);
}
This works just fine. However, I would like to send a parameter (just a simple string value) along from the controller to the partial view I'm creating. This I understand, can be done by the use of a model, like for example:
public PartialViewResult GetPartialView(string someValue)
{
return PartialView("SomePartial", new SomeDummyModel(someValue));
}
But I would like to avoid the model instance if possible, as it seems like a lot of overhead. I want to just send the string value as a parameter. Is that possible?
Instead of passing a custom class such as SomeDummyModel you can simply pass someValue. Assuming that someValue is string from your explanation, that would mean you would accept string in the #model of your partialView.
controller
public PartialViewResult GetPartialView(string someValue)
{
return PartialView("SomePartial", someValue);
}
partial
#model string
<div>Hello, #Model :)</div>
You can also use the ViewData object to pass simple items like that.
public PartialViewResult GetPartialView()
{
ViewData["someValue"] = "hello";
return PartialView("SomePartial", null);
}
And then in the view access it:
<div>#ViewData["someValue"].ToString() :)</div>
This works without a model.
You can put pretty much anything into the ViewData object, you just need to cast it out

mvc passing model to action method

I'm using MVC 5, and have a page where I will list out payments for a contract. there are times when there are no payments associated with a contract. my view brings in the model to list:
#model List<MyProject.Models.PaymentViewModel>
the Action Method on the Payment view looks like:
[HttpGet]
public ActionResult Payment(int id)
{
var payments = contractController.GetPaymentsForActiveContract(id);
return View(payments);
}
Now GetPaymentsForActiveContract returns a List and this works fine when I use
#Html.Partial("partialviews/_Payments")
on my view. but what i'm trying to do now is have another action method get called, which will return either a view which will display a table of payments, or another one which will write out there are none if no payments exists.
I have that action defined as:
public ActionResult GetPayments(List<PaymentViewModel> payments)
{
if (payments.Count > 0)
{
return PartialView("partialviews/_Payments", payments);
}
return PartialView("partialviews/_NoPayments");
}
I'm not sure how to pass the Model into this Action from my view. I'm looking through the #Html methods, but can't seem to find anything which would allow me to call the GetPayments method passing in the model and having it return either Partial View.
If you want to call controller action from view, you can use
#Html.Action()
method and pass payments list as route value
#{
var paymentsList = new List<PaymentViewModel> {new PaymentViewModel(), new PaymentViewModel()};
}
#Html.Action("GetPayments", new { payments = paymentsList })

Partialview result returns null

Partial view does not return any data.When i check with debug tool on PartialView page(_ContentBlock.cshtml), model seem to null.
Controller
public ActionResult Module()
{
int RouteDataValue = default(int);
if (RouteData.Values["id"] != null)
{
RouteDataValue = int.Parse(RouteData.Values["id"].ToString());
}
using (Models.ContentModel db = new Models.ContentModel())
{
var Query = from n in db.PageModule
join m in db.Module on n.ModuleId equals m.ModuleId
where n.PageId == RouteDataValue
select m.PhysicalPath;
return PartialView(Query.Single()); //returns PartialView such as ~/Modules/Content/_ContentBlock.cshtml
}
}
public PartialViewResult ContentBlock()
{
using (Models.ContentModel db = new Models.ContentModel())
{
return PartialView("~/Modules/Content/_ContentBlock.cshtml", db.ContentBlock.Where(n => n.PageId == 2).Single());
}
}
Page.cshtml
#Html.Action("Module")
_ContentBlock.cshtml
#model IEnumerable<Models.ContentBlock>
#foreach (var item in Model)
{
#Html.DisplayFor(n => item.Content)
}
You seem to have used the Html.Partial helper instead of Html.Action. So you were basically only rendering the partial without ever hitting the controller action that is supposed to populate and the model to the partial.
Your page Page.cshtml is calling the partial view action Module using:
#Html.Action("Module")
The action called Module is being executed. In that action, your query results in a path to your view, such as:
"~/Modules/Content/_ContentBlock.cshtml"
That action is returning the single result of that query using:
return PartialView(Query.Single());
What this is doing is passing the name of the view to the PartialView method to return which view is going to be used to display data from the action. In addition, no model data is included in this return.
That's where your problem is. When you return the path to the partial view, you are simply telling the MVC system what view to use to display the data from Module. It won't actually call another partial view. That's not how it works. So your model is null because, you didn't pass any data in your PartialView(...) call.
You have another action called ContentBlock. But that action is not being called because nothing is calling it.
Edit:
Another problem you have is that _ContentBlock.cshtml uses a model of IEnumerable<ContentBlock>, but you're only passing it a .Single() from your ContentBlock action.

Controller searching for view instead of returning a different view method

I have two controller actions outlined below:
public ViewResult TitleStorylines(int id)
{
var vm = Service.Get(id);
vm.IsEditable = User.HasPermission(SecurityPermissionType.ManageStorylines);
return View(vm);
}
public ViewResult TitleStorylinesCreate(TitleStorylineModel model)
{
var created = Service.Create(model);
return TitleStorylines(created.TitleId);
}
I only have one view in my project, called TitleStorylines, which the first controller action handles fine. But when I call the second method, it gives me an error saying that it can't find the view called TitleStorylinesCreate even though I'm explicitly calling the previous method. What gives?
Did you try ?
return View("TitleStorylines",created.TitleId);
EDIT: Based on your update : I guess you are posting your form back the TitleStorylinesCreate. So probably after saving, dont you want to redirect the user back to the Get action of same ?
[HttpPost]
public ViewResult TitleStorylinesCreate(TitleStorylineModel model)
{
var created = Service.Create(model);
return RedirectToAction("TitleStorylines",new { #id=created.TitleId});
}
In the above example we are doing the PRG pattern. Post -> Redirect -> Get
After saving, we are redirecting them back to the first method. It will be a HTTP GET method.
public ActionResult TitleStorylinesCreate(TitleStorylineModel model)
{
var created = Service.Create(model);
return RedirectToAction("TitleStorylines",new { #id=created.TitleId});
}

Can't pass viewmodel to new action by RedirectToAction

I have a form, when user submit the form, I want to direct the user the new view to display the submitted result(transfer viewmode data to display view).
public class HomeController : Controller
{
private MyViewModel _vm;
.....
// POST: /Home/Create
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(MyViewModel vm){
//.....
//set up vm to temp data _vm
_vm = vm;
return RedirectToAction("DisplayData");
}
// GET: /Home/DisplayData
public ActionResult DisplayData()
{
//get temp data for display
return View(_vm);
}
}
When I posted the form, I can create vm and put it to temp data place _vm. But this _vm can be sent to another action DisplayData, it's null in action DisplayData(). It seems that when redirect action even in same controller, _vm is lost although it is Controller var, not action method var.
How to resolve this problem?
It creates a new instance of the controller as it is a new request therefore as you have found it will be null.
You could use TempData to store the vm, TempData persists the data for 1 request only
Good explanation here
One good way is to call
return DisplayData(_vm)
instead of
RedirectToAction("DisplayData")
DisplayData should accept a model anyway.

Resources