How to RedirectToAction in ASP.NET MVC without losing request data

Using ASP.NET MVC there are situations (such as form submission) that may require a RedirectToAction.

One such situation is when you encounter validation errors after a form submission and need to redirect back to the form, but would like the URL to reflect the URL of the form, not the action page it submits to.

As I require the form to contain the originally POSTed data, for user convenience, as well as validation purposes, how can I pass the data through the RedirectToAction()? If I use the viewData parameter, my POST parameters will be changed to GET parameters.

5.08.2008 05:33:41
Here's a question that is similar (on the same topic), but different than this one. Anyway, it still may be of interest to those interested in this question: http://stackoverflow.com/questions/129335/how-do-you-redirecttoaction-using-post-intead-of-get
Chris Pietschmann 24.09.2008 19:37:10
Why aren't you just returning the same view if there's an error? RedirectToAction is usually called if the Model is valid - or am I missing something?!
niico 29.04.2017 17:00:45
5 ОТВЕТОВ
РЕШЕНИЕ

The solution is to use the TempData property to store the desired Request components.

For instance:

public ActionResult Send()
{
    TempData["form"] = Request.Form;
    return this.RedirectToAction(a => a.Form());
}

Then in your "Form" action you can go:

public ActionResult Form()
{
    /* Declare viewData etc. */

    if (TempData["form"] != null)
    {
        /* Cast TempData["form"] to 
        System.Collections.Specialized.NameValueCollection 
        and use it */
    }

    return View("Form", viewData);
}
80
7.02.2016 00:59:36
RedirectToAction(a => a.Form()) doesn't compile for me using MVCv2, are you using MVCv3?
ChrisAnnODell 16.12.2010 15:20:49
This was pre-MVC1 (2008). The lambdas were removed at some stage I believe (there is a codeplex project MVCContrib that reintroduces them, although you may as well use their helper attribute at that stage: stackoverflow.com/questions/1936/…). In mvc2 you should be able to go RedirectToAction("Form"), i.e. name as a string, although I loosely recall that MVC 2 or 3 introduced a helper attribute similar to that in MVCContrib if you are keen to go searching.
Matt Mitchell 19.12.2010 01:29:13

Keep in mind that TempData stores the form collection in session. If you don't like that behavior, you can implement the new ITempDataProvider interface and use some other mechanism for storing temp data. I wouldn't do that unless you know for a fact (via measurement and profiling) that the use of Session state is hurting you.

37
7.08.2008 05:12:32

There is another way which avoids tempdata. The pattern I like involves creating 1 action for both the original render and re-render of the invalid form. It goes something like this:

var form = new FooForm();

if (request.UrlReferrer == request.Url)
{
     // Fill form with previous request's data
}

if (Request.IsPost())
{
     if (!form.IsValid)
     {
         ViewData["ValidationErrors"] = ...
     } else {
         // update model
         model.something = foo.something;
         // handoff to post update action
         return RedirectToAction("ModelUpdated", ... etc);
     }
}

// By default render 1 view until form is a valid post
ViewData["Form"] = form;
return View();

That's the pattern more or less. A little pseudoy. With this you can create 1 view to handle rendering the form, re-displaying the values (since the form will be filled with previous values), and showing error messages.

When the posting to this action, if its valid it transfers control over to another action.

I'm trying to make this pattern easy in the .net validation framework as we build out support for MVC.

8
26.08.2008 19:27:04
I use TempData as well, the problem as I understand it, with your solution Deeno is that if the user was to refresh the page after posting invalid data they would receive a "Would you like to resubmit the form data" confirmation. Using the TempData solution as MattMitchell says eliminates this problem.
user10479 15.09.2008 23:53:18
Cool. Seems someone noticed this basic idea with preview 5 too.
Matt Mitchell 13.10.2008 22:12:59

Take a look at MVCContrib, you can do this:

using MvcContrib.Filters;

[ModelStateToTempData]
public class MyController : Controller {
    //
    ...
}
13
22.02.2018 16:48:19

If you want to pass data to the redirected action, the method you could use is:

return RedirectToAction("ModelUpdated", new {id = 1});
// The definition of the action method like  public ActionResult ModelUpdated(int id);
2
30.11.2013 08:39:03