Storing ModelState in TempData with ASP.NET MVC
October 18, 2008 – 16:19
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.
7 Responses
Thanks, this will be very useful.
I like this attribute, but I had to make two changes so that it world work for me.
1. I had to change it so that it would work for RedirectResults as well as RedirectToRouteResults.
2. I had to change CopyTempDataToModelState so that it would overwrite existing values in the ModelState rather than throwing an error that there was a duplicate.
I’m currently using MVC Beta 1 instead of Preview 5, so I don’t know if these problems were introduced in Beta 1 or not.
Hi Bryan,
Would you be willing to submit a patch with your changes? http://www.codeplex.com/MVCContrib/SourceControl/UploadPatch.aspx
Thanks
[...] this code totally saved me: http://www.jeremyskinner.co.uk/2008/10/18/storing-modelstate-in-tempdata-with-aspnet-mvc/ Posted: Mar 13 2009, 06:16 PM by findleyd Filed under: ASP.NET, [...]
Hi Jeremy,
I’ve patched it with the No. 1 change Bryan suggested, so that it now works when the ‘RedirectResults’ method is called.
Patch ID is 2614
Is it possible for this to work with RenderAction from Futures?
Andy,
Please post details about what you’re trying to do and what isn’t working on the MvcContrib mailing list (http://groups.google.com/group/mvccontrib-discuss)
Thanks