I\'ve been running some experiments with ASP.NET MVC2 and have run into an interesting problem.
I\'d like to define an interface around the objects that will be used
Have you tried placing the [Required] attribute on your model and retesting? It may be having difficulty applying the attribute to an interface.
I had the same issue. The answer is instead of overriding BindModel() in your custom model binder, override CreateModel()...
protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, System.Type modelType)
{
if (modelType == typeof(IPhoto))
{
IPhoto photo = new PhotoImpl();
// snip: set properties of photo to bound values
return photo;
}
return base.CreateModel(controllerContext, bindingContext, modelType);
}
You can then let the base BindModel class do its stuff with validation :-)
After inspecting the source for System.Web.MVC.DefaultModelBinder, it looks like this can be solved using a slightly different approach. If we rely more heavily on the base implementation of BindModel, it looks like we can construct a PhotoImpl object while still pulling the validation attributes from IPhoto.
Something like:
public class PhotoModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
if (bindingContext.ModelType == typeof(IPhoto))
{
ModelBindingContext newBindingContext = new ModelBindingContext()
{
ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(
() => new PhotoImpl(), // construct a PhotoImpl object,
typeof(IPhoto) // using the IPhoto metadata
),
ModelState = bindingContext.ModelState,
ValueProvider = bindingContext.ValueProvider
};
// call the default model binder this new binding context
return base.BindModel(controllerContext, newBindingContext);
}
else
{
return base.BindModel(controllerContext, bindingContext);
}
}
}