Use ModelBinder to Generically Bind Complex Types
[Update: Simone brought my attention to the fact that ComplexModelBinder which comes with the framework does exactly that. You can find more info here]
ASP.NET MVC Preview 5 introduce the ModelBinder attribute that can be used to decorate a complex type in an Action. This allows us to have actions that look like this
public ActionResult Create([ModelBinder(typeof(GenericBinder))] ContactList myList)
Instead of this:
public ActionResult Create(string name, string description)
The problem is that you have to build a Binder for every complex type you want to use as a parameter. For example, Maarten Balliauw created a model binder on his blog and it looks like this:
public class ContactBinder : IModelBinder { #region IModelBinder Members public object GetValue(ControllerContext controllerContext, string modelName, Type modelType, ModelStateDictionary modelState) { if (modelType == typeof(Contact)) { return new Contact { Name = controllerContext.HttpContext.Request.Form["name"] ?? "", Email = controllerContext.HttpContext.Request.Form["email"] ?? "", Message = controllerContext.HttpContext.Request.Form["message"] ?? "" }; } return null; } #endregion }
Now that is a lot of typing and because I am lazy, I decided to create a generic binder that uses reflection and can work with all my complex types.
Note: By generic I mean common – it has nothing to do with .net Generics
Also note that this will only work if you follow these conventions:
- The html field name must match the property name
- User lower case names for the html fields
- You don’t have to user lower case on your model properties
Here is the very rough and untested Generic Binder:
class GenericBinder : IModelBinder { public object GetValue(ControllerContext controllerContext, string modelName, Type modelType, ModelStateDictionary modelState) { var instance = Activator.CreateInstance(modelType); foreach (var prop in modelType.GetProperties()) { prop.SetValue(instance, controllerContext.HttpContext.Request .Form[prop.Name.ToLower()], null); } return instance; } }
If you find any bugs or have a better implementation, please share.
Tags: ASP.NET MVC, mvc, mvcbook








Wed, Sep 3, 2008
ASP.NET MVC