I'm struggling with renderaction, the problem is that it calls the wrong action method on my controller.
On my "Users" controller there are two action methods called edit, one for get and one for post requests:
public virtual ActionResult Edit(int id)
{
//return a view for editing the user
}
[AcceptVerbs(HttpVerbs.Post)]
public virtual ActionResult Edit(UserViewModel model)
{
//modify the user...
}
In my view, I'm calling Renderaction it as follows:
Html.RenderAction("Edit", "Users", new { id = 666});
Now the problem is that I want the GET action method to be rendered. However (perhaps because the model also contains a property called ID?), Renderaction calls my POST action method instead.
What's the proper way to do this? I'm using ASP.NET MVC 3 RC in case it matters.
Thanks,
Adrian
Sub action uses HTTP method of its parent action
The problem is that your view is being rendered after a postback action. All sub-action renderings in the view use the same HTTP method. So POST is being replicated on them. I'm not sure about MVC3, but in MVC2 there was no built-in way to overcome this problem.
So the problem is that you want your Edit()
action to be rendered as a GET on a POST view. Out of the box. No way.
You can of course do it by providing your own functionality = classes.
This won't even compile:
public virtual ActionResult Edit(UserViewModel model) {}
[AcceptVerbs(HttpVerbs.Post)]
public virtual ActionResult Edit(UserViewModel model) {}
You cannot have two methods with the same name and same arguments on the same class. Also why your actions are virtual
?
UPDATE:
Unable to repro. This doesn't seem to be the case:
public class UserViewModel
{
public int Id { get; set; }
}
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Edit(int id)
{
return View(new UserViewModel());
}
[HttpPost]
public ActionResult Edit(UserViewModel model)
{
return View(model);
}
}
And in Index.cshtml
render the edit action calls the correct Edit action (the one with id parameter):
@{Html.RenderAction("edit", "home", new { id = "123" });}
I'm not 100% sure if this is available in MVC3, but in MVC2 (with MvcFutures: Microsoft.Web.MVC) I would use:
Html.RenderAction<UsersController>(c => c.Edit(666));
I know this is extremely old, and we're on MVC5 now - but this is still the behavior exhibited when running Html.RenderAction()
.
My solution to this particular case, was to make a check in my [HttpPost]
action for values on my view model, and if they were null (or whatever) I called my return Edit()
, and if they weren't I called AntiForgery.Validate()
to properly validate the token.