0

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?

Mikayil Abdullayev
  • 12,117
  • 26
  • 122
  • 206
  • The input(s) should be within the form element, but it would be better to set the value in the `Html.BeginForm()` method –  Aug 19 '14 at 13:01
  • What's then the difference between the methods Save and Cancel. Why don't I have to pass anything in the Save method? – Mikayil Abdullayev Aug 19 '14 at 14:30
  • There's no difference. Neither will work with the code snippets you posted here. If the 'Save' method is working its because you have omitted something (none of what you have shown will even compile). I'll post an answer with a bit more detail. –  Aug 19 '14 at 22:40

1 Answers1

1

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 })) {
  ....