Use ModelBinder to Generically Bind Complex Types
September 3, 2008
[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.
Posted in

content rss

Add New Comment
Viewing 6 Comments
Thanks. Your comment is awaiting approval by a moderator.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Add New Comment
Trackbacks