How to create a model binder for decimal numbers which will throw exception if users are sending it in a wrong format?
I need something like this:
2 = OK
2.123 = OK
2,123 = throw invalid format exception
How to create a model binder for decimal numbers which will throw exception if users are sending it in a wrong format?
I need something like this:
2 = OK
2.123 = OK
2,123 = throw invalid format exception
Look at this article http://haacked.com/archive/2011/03/19/fixing-binding-to-decimals.aspx/
You can just use standard binder with simple check like this
public class DecimalModelBinder : IModelBinder
{
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
{
ValueProviderResult valueResult = bindingContext.ValueProvider
.GetValue(bindingContext.ModelName);
ModelState modelState = new ModelState { Value = valueResult };
object actualValue = null;
if (valueResult.AttemptedValue.Contains(","))
{
throw new Exception("Some exception");
}
actualValue = Convert.ToDecimal(valueResult.AttemptedValue,
CultureInfo.CurrentCulture);
bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
bindingContext.Model = actualValue;
return true;
}
}
EDIT: According to @Liam suggestion you have to add this binder to your configuration first
ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());
Above code throws exception in the case of bad decimal separater, but you should use model validation to detect that kind of errors. It is more flexible way.
public class DecimalModelBinder : IModelBinder
{
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
{
ValueProviderResult valueResult = bindingContext.ValueProvider
.GetValue(bindingContext.ModelName);
ModelState modelState = new ModelState { Value = valueResult };
object actualValue = null;
try
{
if (valueResult.AttemptedValue.Contains(","))
{
throw new Exception("Some exception");
}
actualValue = Convert.ToDecimal(valueResult.AttemptedValue,
CultureInfo.CurrentCulture);
}
catch (FormatException e)
{
modelState.Errors.Add(e);
return false;
}
bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
bindingContext.Model = actualValue;
return true;
}
}
you don't throw exception but just add validation error. You can check it in your controller later
if (ModelState.IsValid)
{
}