Well I looked into this. ASP.NET provides a common location for registering the implementation of IControlBinders. They also have the basics of this working via the new Controller.UpdateModel method.
So I essentially combined these two concepts by creating an implementation of IModelBinder that does the same thing as Controller.UpdateModel for all public properties of the modelClass.
public class ModelBinder : IModelBinder
{
public object GetValue(ControllerContext controllerContext, string modelName, Type modelType, ModelStateDictionary modelState)
{
object model = Activator.CreateInstance(modelType);
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(model);
foreach (PropertyDescriptor descriptor in properties)
{
string key = modelName + "." + descriptor.Name;
object value = ModelBinders.GetBinder(descriptor.PropertyType).GetValue(controllerContext, key, descriptor.PropertyType, modelState);
if (value != null)
{
try
{
descriptor.SetValue(model, value);
continue;
}
catch
{
string errorMessage = String.Format("The value '{0}' is invalid for property '{1}'.", value, key);
string attemptedValue = Convert.ToString(value);
modelState.AddModelError(key, attemptedValue, errorMessage);
}
}
}
return model;
}
}
In your Global.asax.cs you'd need to add something like this:
protected void Application_Start()
{
ModelBinders.Binders.Add(typeof(Contact), new ModelBinder());