I have a Kendo NumericTextbox
@(Html.Kendo().NumericTextBoxFor(m => m.SomeDecimal)
.Name("SomeDecimal")
.Min(0)
.Max(99999999)
.Decimals(2)
)
When posting my form containing this NumericTextbox the value of SomeDecimal is set to null in the model.
Please note: I replaced the Kendo NumericTextbox with a normal textbox and had the same issue because the number that was entered contained a full stop (.) instead of a comma (,). When I replaced the full stop with a comma everything worked as expected.
Do I have to specify a different culture perhaps?
I found a workaround for this problem,
I created a new class DecimalModelBinder to overwrite the default model binding of decimal fields. The code is below. Here I attempt to convert the decimal value, if the conversion fails I replace all full stops with commas and try to convert again. If the second conversion attempt fails I replace all commas with full stops and try again.
public class DecimalModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
var modelState = new ModelState {Value = valueResult};
object actualValue = null;
try
{
// Try to convert the actual number that was recieved.
actualValue = Convert.ToDecimal(valueResult.AttemptedValue, CultureInfo.CurrentCulture);
}
catch
{
try
{
// Replace any . with , and try to convert.
actualValue = Convert.ToDecimal(valueResult.AttemptedValue.Replace('.',','), CultureInfo.CurrentCulture);
}
catch
{
try
{
// Replace any , with . and try to convert.
actualValue = Convert.ToDecimal(valueResult.AttemptedValue.Replace(',', '.'), CultureInfo.CurrentCulture);
}
catch (Exception ex)
{
modelState.Errors.Add(ex);
}
}
}
bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
return actualValue;
}
}
You have to add the DecimalModelBinder in your Global.asx file
protected void Application_Start()
{
RouteTable.Routes.MapHubs();
AreaRegistration.RegisterAllAreas();
ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());
ModelBinders.Binders.Add(typeof(decimal?), new DecimalModelBinder());
// All other code.
}