Max Max - 27 days ago 10
ASP.NET (C#) Question

ASP.NET Core localization decimal field dot and comma

I have a localized ASP.NET Core Web Application: en-US and it-IT.

On en-US the decimal separator is dot, in it-IT the decimal separator is comma.

I have this ViewModel

public class MyViewModel
{
public int Id {get; set; }

// Omitted

public decimal? Amount{get; set;}

}


For the decimal field when I render the create/edit page on en-US the html textbox render


1000.00


If I POST the form, the operation complete without errors.

So far so good.

When I render the create/edit page on it-IT the html textbox render


1000,00 (notice the comma)


And IF I try to POST the form, (CLIENT) validation fail with


The field Amount must be a number.


I read about the IModelBinder but I understand is for mapping the viewModel when the form is posted on the server, on my case I'm blocked by the client-side validation.

The better is to use dot when en-US and comma when it-IT, but it's fine using only the dot

Max Max
Answer Source

After digging depth the problem I found two solution:

The comment from Stephen Muecke where explain how to add the required jquery to the input for a validation for comma and dot

A custom InputTagHelper where transform the comma into dot. Here I added only a decimal type but obviously you can add float and double.

[HtmlTargetElement("input", Attributes = ForAttributeName, TagStructure = TagStructure.WithoutEndTag)]
public class InvariantDecimalTagHelper : InputTagHelper
{
    private const string ForAttributeName = "asp-for";

    private IHtmlGenerator _generator;

    [HtmlAttributeName("asp-is-invariant")]
    public bool IsInvariant { set; get; }

    public InvariantDecimalTagHelper(IHtmlGenerator generator) : base(generator)
    {
        _generator = generator;
    }

    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        base.Process(context, output);

        if (IsInvariant && output.TagName == "input" && For.Model.GetType() == typeof(decimal))
        {
            decimal value = (decimal)(For.Model);
            var invariantValue = value.ToString(System.Globalization.CultureInfo.InvariantCulture);
            output.Attributes.SetAttribute(new TagHelperAttribute("value", invariantValue));                
        }
    }
}