The default Model Binder in ASP.NET MVC works fine for most cases. Most of you have probably registered custom binders with it plenty of times.
ModelBinders.Binders.Add(typeof(ILoadProvider), new LoadProviderModelBinder());
The issue is that that it’s limited to binding the exact type you add to its dictionary. The ILoadProvider registered above will invoke my LoadProviderModelBinder as long as the controller action parameter is of type ILoadProvider. But what if you have a type that derives from ILoadProvider and still want your custom binding to occur?
Thankfully this is very simple in ASP.NET MVC 3. It comes with a new extensibility point, IModelBinderProvider, and works just like the other providers.
public interface IModelBinderProvider
{
IModelBinder GetBinder(Type modelType);
}
InheritanceAwareModelBinderProvider
With this interface, we are able to create a very simple InheritanceAwareModelBinderProvider.
/// <summary>
/// Adds inheritance support when registering model binders.
/// Any model binders added here will be invoked if the Type being bound inherits from the type registered.
/// </summary>
public class InheritanceAwareModelBinderProvider : Dictionary<Type, IModelBinder>, IModelBinderProvider
{
public IModelBinder GetBinder(Type modelType)
{
var binders = from binder in this
where binder.Key.IsAssignableFrom(modelType)
select binder.Value;
return binders.FirstOrDefault();
}
}
Usage
Register the Model Binder Provider just as you normally would register Model Binders. For example, in Global.asax
var binderProvider = new InheritanceAwareModelBinderProvider
{
{ typeof (ILoadProvider), new LoadProviderModelBinder() }
};
ModelBinderProviders.BinderProviders.Add(binderProvider);
Given the example above, if I’m binding to a type that that inherits from ILoadProvider my LoadProviderModelBinder will still handle the binding.
Technorati Tags:
aspnet mvc