How do I maintain ModelState errors when using RedirectToAction?
I have some code that saves a ticket in our system. If there is an error it does a RedirectToAction()
. The problem is that I don't seem to have my errors in the new action. How can I fix this?
ModelState.AddModelError("_FORM", "Unable to save ticket");
ModelState.AddModelError("_FORM", "Phone number was invalid.");
ModelState.AddModelError("_FORM", "Lane number is required.");
return RedirectToAction("CreateStep", "Ticket");
I know some have suggested using TempData
, but how would I get each error out of the ModelState
?
Thanks.
The PRG pattern is ok, but I did this:
Base controller:
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (TempData["ModelState"] != null && !ModelState.Equals(TempData["ModelState"]))
ModelState.Merge((ModelStateDictionary)TempData["ModelState"]);
base.OnActionExecuted(filterContext);
}
Action (I'm using xVal):
try
{
user.Login();
AuthenticationManager.SignIn(user);
}
catch (RulesException rex)
{
// on bad login
rex.AddModelStateErrors(ModelState, "user");
TempData["ModelState"] = ModelState;
return Redirect(Request.UrlReferrer.ToString());
}
The action throws an exception, adds the ModelState
to TempData
and redirects back to the referrer. Since the action is caught, OnActionExecuted
is still executed, but the first time around the ModelState
is the same as TempData["ModelState"]
, so you don't want to merge with yourself. When the redirect action is executed, OnActionExecuted
fires again. This time, if there's anything in TempData["ModelState"]
, it merges with this action's ModelState.
You could expand it to multiple models by using TempData["ModelState.user"] = ModelState
and then merging every TempData
object that starts with ModelState.
.
I know this thread is old, but this blog about ASP.NET Best Practices has some excellent suggestions.
#13 on the page deals with using 2 Action filters to save and restore ModelState
between redirects.
This is the pattern that my work uses, and I love it.
Here's the simplified example:
[ImportModelStateFromTempData]
public ActionResult Dashboard()
{
return View();
}
[AcceptVerbs(HttpVerbs.Post), ExportModelStateToTempData]
public ActionResult Dashboard(string data)
{
if (ValidateData(data))
{
try
{
_service.Submit(data);
}
catch (Exception e)
{
ModelState.AddModelError(ModelStateException, e);
}
}
return RedirectToAction("Dashboard");
}
this blog post describes how you could implement the PRG-Pattern in MVC http://blog.simonlovely.com/archive/2008/11/26/post-redirect-get-pattern-in-mvc.aspx
hth
Use the TempData[] Collection
The tempdata is stored from one request to the next, then its gone.