Reputation: 7135
I've created a custom model binder based on an article from Haacked. Here's the code:
namespace MyNamespace.Project.ModelBinders
{
public class DecimalModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
string modelName = bindingContext.ModelName;
ValueProviderResult valueResult = bindingContext.ValueProvider.GetValue(modelName);
ModelState modelState = new ModelState { Value = valueResult };
object actualValue = null;
try
{
//replace commas with periods
actualValue = Convert.ToDecimal(valueResult.AttemptedValue.Replace(",", "."));
}
catch (Exception ex)
{
modelState.Errors.Add(ex);
}
bindingContext.ModelState.Add(modelName, modelState);
return actualValue;
}
}
}
When MVC loads a view where the controller action is something like this:
public ActionResult Index(decimal amount)
It seems to fire the model binding and add the error and this is because amount at this point is null because I have a valid use case where index can be loaded with or without parameters (QueryString). As far as I know MVC doesn't support typical OO method overloading such that you have:
public ActionResult Index(decimal amount) {}
public ActionResult Index() {}
So, would it be valid to add a null check to my custom model binder to avoid the error that is raised in the try block, or would this interfere with validation?
Upvotes: 1
Views: 1804
Reputation: 5847
I see multiple points here in general. First one is regarding this:
As far as I know MVC doesn't support typical OO method overloading...
That's right, but it has a very flexible routes configuration to help with such problems.
You could configure separate routes for calls having the parameter or not having one. I didn't try that, but this would be a sample using Attribute Routing.
[Route("index/{amount}"]
public ActionResult IndexWithAmount(decimal amount) {}
[Route("index")]
public ActionResult Index() {}
Another thing you can do, as described here is to not use the Model Binder globally but rather enable it only on specific routes:
public ActionResult Index(
[ModelBinder(typeof(DecimalModelBinder))]decimal amount) {}
Upvotes: 1