Currently trying to rework a .NET 4.8 MVC application to support globalization (needs to support both English and French). So far, everything has been working fine.
The issue, however, is with decimal input. This is a financial application, so it is important that I deal with input boxes that are set to type="number"
. Strictly speaking, I know that the value 15000,25
is not considered a number, and will not convert implicitly to a decimal (the backing field data type that I use in my view model). With this in mind, I have a custom model binder:
public class DecimalModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
if (valueProviderResult == null)
{
return base.BindModel(controllerContext, bindingContext);
}
if (string.IsNullOrEmpty(valueProviderResult.AttemptedValue))
{
return null;
}
var result = decimal.TryParse(valueProviderResult.AttemptedValue, NumberStyles.Currency, CultureInfo.InvariantCulture, out decimal covertedOutput);
if (result)
{
return covertedOutput;
}
return null;
}
}
This model binder is then registered in the Global.asax file. The above appears to work to an extent...especially in Firefox, in that I can enter 15000,25 into a form input and what happens on the backend is that 15000.25 is recorded in the database.
This is a different story in chrome, as
- I cannot enter 15000,25 as a value, only decimal point based numbers and
- on the reload from the server - chrome will try and take 15000.25 and parse it as 15000,25 in the input...which fails, with the error:
The specified value "15000,25" cannot be parsed, or is out of range
My question is this - should I force users to always deal with true decimal based numbers? So stop them from entering 15000,25 but allow 15000.25? or is there a way around this / best practice that I'm just not seeing?
Here is the decimal field that I'm working with. Both the form control and the view model property:
@Html.TextBoxFor(model => model.SellAmount, "{0:f2}", new {min = "0", type = "number", step = "1000" })
public decimal? SellAmount { get; set; }