I have the following classes:
public class Truck {
public Wheel Wheel { get; set; }
}
public class Wheel {
public int Number { get; set; }
}
And I registered the following model binder:
ModelBinders.Binders.Add(typeof(Wheel), new WheelModelBinder());
And:
public class WheelModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
throw new NotImplementedException();
}
}
If I pass in:
public ActionResult(Wheel wheel) { ... }
The model binder gets hit and throws an exception. If I pass in
public ActionResult(Truck Truck) { ... }
The model binder doesn’t get hit.
In my application, every time Wheel goes in (whether or not it is nested within another type), I want the model binder to pick it up and manipulate the properties on wheel. What’s the best way to accomplish this?
Edit: Using EditorFor() correctly binds me, but I’m unable to arbitrarily edit the property. Using the above example:
public class WheelModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var valueProviderResult = bindingContext.ValueProvider.GetValue("Wheel.Number");
return null;
}
}
This will correctly get the wheel property. However, I might have a new, more complex object:
public class Cars {
public class Truck { get; set; }
}
This breaks the ValueProvider and I will need to do, … GetValue("Truck.Wheel.Number") Am I abusing ModelBinder? Is there a better way to achieve my result (assume my result is to do an external lookup to make sure property Number is valid and if not, set it to something else).
Actually, your ModelBinder and model will work as defined.
The component tripping you up is the view. If you use the following:
then the view will generate the correctly named elements to be consumed by your custom ModelBinder.
However, in this scenario, you do not need a custom ModelBinder, as the DefaultModelBinder will handle your nested model as long as MVC’s conventions are followed. Generally, a custom ModelBinder is for (1) a complex custom type or model, which the DefaultModelBinder cannot consume, or (2) where you are using a custom naming convention.