I have controller called Documents with three action methods:
public ActionResult Save(string returnUrl){
TempData["returnUrl"]=returnUrl;
return View(viewName: "Save");
}
[HttpPost]
public ActionResult Save(string returnUrl){
return Redirect(returnUrl);
}
and
[HttpPost]
public ActionResult Cancel(string returnUrl){
return Redirect(returnUrl);
}
And here's the content of the Save.cshtml view:
@Html.Hidden(TempData["returnUrl"].ToString())
@using (Html.BeginForm){
<!--Some html here-->
<input type="submit" value="Save"/>
}
@using (Html.BeginForm(actionName:"Cancel",controllerName:"Documents")){
<input type="submit" value="Cancel"/>
}
Of course, the above code does not reflect what I need to do in real world but one problem made me strip my code down to this simplest stage. The problem is that the returnUrl
argument is null when I call the Cancel
action method. Why is that?
In order to post back to FormCollection
, inputs associated with the form need to be located inside the <form>
tag (except if using the form attribute). In your case where you have 2 forms and need to post back the value of returnUrl
, you would need 2 inputs. This will create elements with duplicate id's if using html helpers. A better approach would be to include the value in the form element, for example
Controller
[HttpGet]
public ActionResult Save(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
return View("Save");
}
[HttpPost]
public ActionResult Save(string returnUrl, MyModel, model)
{
....
}
[HttpPost]
public ActionResult Cancel(string returnUrl, MyModel, model)
{
....
}
View
@using (Html.BeginForm("Save", "Documents", new { ReturnUrl = ViewBag.ReturnUrl })) {
....
@using (Html.BeginForm("Cancel", "Documents", new { ReturnUrl = ViewBag.ReturnUrl })) {
....