0

I have a decimal field in my modal.

public partial class MyModel
{
    public decimal? BudgetAantalDecimal { get; set; }
}

I show this in my form with

@Html.EditorFor(model => model.BudgetAantalDecimal, new { htmlAttributes = new { @class = "form-control decimal-small inline" } })

When I fill in the value 100 the field is filled in the model. When I fill in the value 100.66 the value is null in my model.

When I change my language setting from Dutch to US format I can use the value 100.66. My customer has the Dutch language setting set in Windows. How can I overcome this issue?

Danny
  • 746
  • 2
  • 8
  • 20
  • Is your server processing the request in the Dutch culture? – Colin Mackay Dec 24 '15 at 14:30
  • How can I verify that? If I go to my control panel of the server and on the first tab where it says format. If I change from Dutch to US then it works. The system locale is still US. The first tab is only for logged in user I think. In Dutch the decimal seperator is a dot and in US a comma – Danny Dec 24 '15 at 14:33
  • 1
    The ASP.NET process should report Thread.CurrentUICulture/CurrentCulture. That's what will be used when parsing numbers. – Colin Mackay Dec 24 '15 at 14:40

1 Answers1

1

You'll need to add a custom model binder to deal with the changing punctuation when it comes to decimals. This blog goes over step by step, but I'll recreate some here in case the link breaks.

First, you need to create the binder:

public class DecimalModelBinder : IModelBinder {
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) {
        var valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        var modelState = new ModelState { Value = valueResult };
        var actualValue = null;
        try {
            actualValue = Convert.ToDecimal(valueResult.AttemptedValue, 
                CultureInfo.CurrentCulture);
        }
        catch (FormatException e) {
            modelState.Errors.Add(e);
        }

        bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
        return actualValue;
    }
}

After that, all you need to do is add it to your config so it knows about it:

protected void Application_Start() {
    AreaRegistration.RegisterAllAreas();

    ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());

    // All that other stuff you usually put in here...
}
krillgar
  • 12,596
  • 6
  • 50
  • 86
  • That modelbinder works. I no longer get a null value. But when I fill in number 100.75 The converted value is 10075. So should I not use CurrentCulture but always US? Because the 75 should be after the decimal seperator – Danny Dec 24 '15 at 14:50
  • I would put a breakpoint in that try block, and see what it gives you for `valueResult.AttemptedValue`. You can then use the Immediate Window to try out the different cultures. – krillgar Dec 24 '15 at 14:52
  • CultureInfo.InvariantCulture this works on my dev and customer site. – Danny Dec 24 '15 at 14:56
  • The only thing that I don't get is why if I use dutch setting and no model binder the value gets null instead of for example when I use 100.75 translated into 10075 – Danny Dec 24 '15 at 15:10
  • It doesn't work because it throws an exception when trying to convert the string to a decimal, so instead of blowing up it just says there is no value. – krillgar Dec 24 '15 at 15:18
  • Can't the validation with jquery get this and show the user what format he should use? – Danny Dec 24 '15 at 15:21
  • You can write a function to force it to either `.` or `,`. However, this is a problem specific to ASP.NET MVC, and other platforms may not have similar problems. jQuery thinks it is a valid value for its purposes. – krillgar Dec 24 '15 at 15:26