Storing ModelState in TempData with ASP.NET MVC

MVC Preview 5 introduced the contept of ModelState for storing validation failures.

As the ModelState is part of the ViewData, it is only available for the current request. This means that you cannot redirect to another action in order to show the error summary, instead you have to render a view directly from your Save action. Personally I don't think this is a good idea - the Save action should just try and save changes, and then redirect to another action to display validation errors.

One solution is to store the ModelState inside the TempData (as anything added to the TempData will be made available to the next HTTP request). It is possible to use an ActionFilterAttribute to make this happen automatically.

Under the covers, TempData makes use of ASP.NET Session State which means that every object that is stored in TempData needs to be marked as Serializable if you are using an out of process session store. Unfortunately, the ModelStateDictionary is not marked as serializable, so in order for this approach to work it is necessary to copy the contents of the ModelState into a temporary serializable dictionary.

I've made the code available in MvcContrib. You can use it by decorating your controllers with the ModelStateToTempData attribute:

using MvcContrib.Filters;
 
[ModelStateToTempData]
public class MyController : Controller {
  //...
}

The filter has the following features:

  • If your controller action returns a RedirectToRouteResult, anything in the ModelState dictionary will be wrapped in a ModelStateSerializable class and stored in TempData.
  • If your action returns a ViewResult, then any ModelState objects that were previously copied to TempData will be re-added to the ModelState dictionary.

Written on October 18, 2008