I have looked in to the code of the mvc DefaultModelBinder implementation. When binding a model DefaultModelBinder look up the properties of the model using GetModelProperties(). The following is how DefaultModelBinder look up the properties :
protected virtual ICustomTypeDescriptor GetTypeDescriptor(ControllerContext controllerContext, ModelBindingContext bindingContext) {
return TypeDescriptorHelper.Get(bindingContext.ModelType);
}
TypeDescriptorHelper.Get is using ModelType which is the partent type (in my case FormElement), so the properties of the child class (TextBox, Combo) are not retrieved.
You can override the method and change the behavior to retrieve the specific child type as below.
protected override System.ComponentModel.PropertyDescriptorCollection GetModelProperties(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
Type realType = bindingContext.Model.GetType();
return new AssociatedMetadataTypeTypeDescriptionProvider(realType).GetTypeDescriptor(realType).GetProperties();
}
protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
{
ValueProviderResult result;
result = bindingContext.ValueProvider.GetValue(bindingContext.ModelName + ".ControlType");
if (result == null)
return null;
if (result.AttemptedValue.Equals("TextBox"))
return base.CreateModel(controllerContext,
bindingContext,
typeof(TextBox));
else if (result.AttemptedValue.Equals("Combo"))
return base.CreateModel(controllerContext,
bindingContext,
typeof(Combo));
return null;
}