I found that SetProperty for DefaultModelBinder is only called when it finds a property and tries to set it.
With this in mind, this is my NullModelBinder.
public class NullModelBinder : DefaultModelBinder { public bool PropertyWasSet { get; set; } public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { object model = base.BindModel(controllerContext, bindingContext); if (!PropertyWasSet) { return null; } return model; } protected override void SetProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor, object value) { base.SetProperty(controllerContext, bindingContext, propertyDescriptor, value); PropertyWasSet = true; } }
So, only if the infrastructure has detected a property in the request and tries to set it to the model, I return the model created by BindModel .
Note:
My approach is different from the NullBinders of the previous answers, because it passes once through each property, and in the worst case, the other NullBinders go twice.
In this snnipet code:
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { object model = base.BindModel(controllerContext, bindingContext);
When the call to base.BindModel is called .Net passes through each property of the model, trying to find them and set them when creating the model.
Then CustomModelBinder again returns to any property until it finds one of those present in the request, in which case it returns the model created by .NET, otherwise returns null.
Thus, if the property is not set, we would effectively go through each property of the model twice.