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
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 != null && 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));
}
}
}
For use this 2nd solution you simply add asp-is-invariant to your input, like this
<input asp-for="AmountSw" class="form-control" asp-is-invariant="true" />
The conversion fails because ASP.NET tries to convert the value with its current culture (check this link).
You need to set the culture in the current thread of the request. The browser will send the languages it is currently using and supportin with Request.UserLanguage
.
You can impliment a custom filter, a http module or use the event structure of mvc to set the culture automatically for every request. Check this link for a sample.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With