Getting started with MVCContrib: Filters
What is MVCContrib? MVCContrib is a open source project was designed to add functionality and ease-of-use to the out of the box experience of the ASP.NET MVC Framework. It kicks in where MVC on its own has left off. MVCContrib is hosted on CodePlex at http://mvccontrib.codeplex.com and it also a CodePlex Foundation Project.
In this post I’m going to cover a couple of the Action Filters that are included with MVCContrib, ModelStateToTempData and PassParametersDuringRedirect.
ModelStateToTempData
When you have this filter decorating your action method (or at the controller level) you will get a behavior in which that when model state gets created post model binding you might have a state in which you want available to another action method. This happens when you are practicing the Post-Redirect-Get Pattern (PRG).
Let’s say you have a CustomerEditModel that coming from a web form. You need a Post Action that takes in a CustomerEditModel and out of the box that DataAnnotations will engage and validate your model. Below is a model with two attributes, Required and DisplayName. Required may or may not be what you think it means and DisplayName gives you an opportunity to give your labels a different name than from the reflected property type name when using the template helpers (go read Brad’s series now).
public class CustomerEditModel
{
[Required]
[DisplayName("First Name")]
public string FirstName { get; set; }
[Required]
[DisplayName("Last Name")]
public string LastName { get; set; }
}
[HttpPost]
public ActionResult CreateCustomer(CustomerEditModel customerEditModel)
{
if (ModelState.IsValid)
{
//Do Something Worthy of your NEW Customer
return RedirectToAction("Success");
}
return RedirectToAction("FixErrors");
}
[HttpGet]
public ActionResult FixErrors()
{
return View("Index");
}
Ok back to the story. When you submitted a nice clean valid model and you flow into the ModelState.IsValid block life is good. When you had some validation issues and you flow to the FixErrors RedirectToAction something particular needs to happen. ModelState has some your validation results that you will want to use to display validation hints back to your end users. The problem is that ModelState isn’t carried over, without any intervention to the next Action method being called.
Enter the ModelStateToTempData Attribute
Add a [ModelStateToTempData] to the action method that the modelstate is being generated from, let’s call it the sender, AND the action method that needs to use it, maybe call it the reciever?
[HttpPost]
[ModelStateToTempData]
public ActionResult CreateCustomer(CustomerEditModel customerEditModel)
{
if (ModelState.IsValid)
{
//Do Something Worthy of your NEW Customer
return RedirectToAction("Success");
}
return RedirectToAction("FixErrors");
}
[HttpGet]
[ModelStateToTempData]
public ActionResult FixErrors()
{
return View("Index");
}
What’s happening on the sending side with these attributes is when a RedirectToRouteResult is returned from an action (in this case we’re using RedirectToAction) any data that is the ModelState dictionary will be copied into TempData – A.U.T.O.M.A.T.I.C.A.L.L.Y. You don’t have to manually do it yourself!

What’s happening on the receiving side with these attributes is when a ViewResultBase is returned from an action (in this case we’re using View) all the data that was previously put into TempData is copied out of TempData and put back into ModelState
In this case since we’re in the FixErrors action the errors that we just got back from the [ModelStateToTempData] attribute will be displayed on the user form. Additionally we’re also getting back the values of the "bad submission" from the end user so that for non-trivial (or really any) forms they don’t have to re-enter their data.
PassParametersDuringRedirect
Since we live in a perfect world and our information management is so well done that our users get all the forms filled out perfectly that that always drop into the ModelState.IsValid block every time. Maybe we can just render the view from there … NO! My post, my rules. Thou shalt not render view from Post Methods. We have to PRG our way out of there. In this case we’d do something interesting with some persistence and then we’ll take the user to a ‘You Are Teh Awesome‘ page.
Let’s take the same controller action methods but add one more attribute to them, [PassParametersDuringRedirect]
[HttpPost]
[ModelStateToTempData]
[PassParametersDuringRedirect]
public ActionResult CreateCustomer(CustomerEditModel customerEditModel)
{
if (ModelState.IsValid)
{
//Do Something Worthy of your NEW Customer
return this.RedirectToAction(x => x.Success(customerEditModel));
}
return RedirectToAction("FixErrors");
}
[HttpGet]
[PassParametersDuringRedirect]
public ActionResult Success(CustomerEditModel customerEditModel)
{
return View(customerEditModel);
}
I’d like to point out that the difference between the two RedirectToAction call in the CreateCustomer Action Method. The second one, the one that ships with Asp.NET MVC and the first one has the nice expression in there. This is another nugget that comes with MVCContrib. This flavor of the RedirectToAction extension method will take in a an expression and make sure that the destination method will have the correct parameters passed to it.
The new attribute added to the methods, [PassParametersDuringRedirect] is bringing some more pleasant PRG stuff to the controller. After the valid customer has been ‘persisted’ we want to show the user a Sucess page. In this case we want to show the model (or maybe another model with additional information) thus the method signature as so public ActionResult Success(CustomerEditModel customerEditModel). This is very similar to the [ModelStateToTempData] behaviour.
I hope this information has helped. Just until very recently I didn’t know these things were in the MVCContrib project and now I have some code to delete from our current code base.
Cool stuff on the PassParametersDuringRedirect attr. I never looked at that one. Might need to re-investigate!