aspnetcore: Localised number format and wrong input type for decimal fields
Describe the bug
With a model that contains a decimal property, this doesn’t work with a locale that uses a decimal comma:
<input asp-for="Number">
<input asp-for="Number" type="number">
To Reproduce
Steps to reproduce the behavior:
- Using this version of ASP.NET Core 2.1.5
- Create the model class and the HTML razor view, then run it
Code:
class Model
{
public decimal Number { get; set; } = 1.0m;
}
Expected behavior
This should be the rendered HTML:
<input type="number" name="Number" value="1.0">
This happens instead, for the two view variants from the top:
<input type="text" name="Number" value="1,0">
<input type="number" name="Number" value="1,0">
The first issue is that the decimal type isn’t rendered with the type="number" attribute. If I fix this myself by adding the attribute, the field remains completely empty because there is a comma instead of a point in the value. This shouldn’t be localised because then no browser or frontend library can handle the value anymore.
PS: I haven’t even got to try what happens when the correct value “1.0” is sent back to the controller and the model binder should convert it to a decimal type. It probably fails for the same reason.
[User reference: Configuration/Endpoint/Edit/Factor]
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 12
- Comments: 50 (19 by maintainers)
Commits related to this issue
- Asp.Net Core Bug workaround... Forced culture to be en-US https://github.com/dotnet/aspnetcore/issues/6566 — committed to chakian/expense-tracker-web by chakian 4 years ago
- Develop (#39) * Translate all turkish (#30) * Unauthorized pages are translated * Changed ID to Name * Added Display annotations * HTML changes for Turkish translation. See #29 * Trans... — committed to chakian/expense-tracker-web by chakian 4 years ago
- Develop (#40) * Translate all turkish (#30) * Unauthorized pages are translated * Changed ID to Name * Added Display annotations * HTML changes for Turkish translation. See #29 * Trans... — committed to chakian/expense-tracker-web by chakian 4 years ago
- Develop (#42) * Translate all turkish (#30) * Unauthorized pages are translated * Changed ID to Name * Added Display annotations * HTML changes for Turkish translation. See #29 * Trans... — committed to chakian/expense-tracker-web by chakian 4 years ago
@javiercn What does that mean, “affected-few”? That most ASP.NET Core users in the world use English number formats? That would be new to me. And what does “severity-minor” mean? That it’s not a blocking issue to not be able to use decimal numbers in forms? That’s a strange ranking app you use there. Must be heavily US-biased.
Bro, It’s only been almost two years. Give them some time to sort this out. Come on man!
@mkArtakMSFT Can you please explain why you believe the question has been answered / the bug has been fixed? I cannot see how this is the case. Please reopen until this has been fixed. In case you didn’t know, there are other regions in the world than those that use a decimal point. And currently I can’t use proper HTML with decimal numbers with ASP.NET Core MVC data binding.
It’s really sad to see this issues is pushed from version to planning to version but never really fixed…
…really Microsoft?!? That’s not how an issue of this gravity of e.g. german speaking world should be treated!
Yep… I thought so^^
See this Gist here: FIX: Localised number format and wrong input type for decimal fields
@mkArtakMSFT Thanks for the update. I’d suggest you put a bold warning in the ASP.NET Core documentation then which says that this product does not support other server environments than English (and few more) and will not for an unspecified time. At least everybody knows what to expect then, and when to look for alternatives.
We’ve moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.
FTR, no jQuery validation around here. The problem solely lies in ASP.NET Core.
I’m tired of searching for a permanent solution to this problem in every new project for years. Can you please solve this problem in 7.0-rc1 milestone?
Seems to be an old issue: https://github.com/aspnet/Mvc/issues/2780 https://github.com/aspnet/Mvc/issues/6024
With locals that use comma as the decimal separator, the rendered value in the text input field causes the client-side validation to fail (when using the jQuery validation library that comes with the razor pages project template).
The expectation by the validator is that the browser returns the value as a floating-point number, but since it only does this for type=“number”, it fails the validation.
The issue does not seem to be the client-side validation, however, people do seem to workaround this by hacking the client-side validator: https://weblogs.asp.net/jdanforth/jquery-validate-and-the-comma-decimal-separator
type=“number” fields use invariant culture and we should consider parsing as such in model binding.
@mkArtakMSFT Did you want to reopen this issue?
API review notes:
API Approved!
Hm, I really don’t have a preference here. Maybe I like “render” a bit more just because the “ing” doesn’t really add any important information. Totally willing to change my mind though!
I think
FormInputRenderModemight be good becauseFormValueFormattingModedoesn’t necessarily represent the fact that this option also controls whether hidden<input name="__Invariant" ... />elements are generated.I’ve chosen
DetectCultureFromInputTypeinstead ofInvariantCulturebecause it still might useCurrentCulturefor some input types.And I think
AlwaysUseCurrentCulturehighlights that while the other option may useCurrentCulture, this one will definitely use it.Just ran into this.
I did this :
<input asp-for="Number" class="form-control" type="number" value="@Model.Number.ToString("N", CultureInfo.InvariantCulture)" />It is ugly, and I don’t like it, but hey, such is life for we few, we rest-of-the-world, minor-severity-bug-affected few.
// Edit: Just discovered that
Number.ToString("F", CultureInfo.InvariantCulture)might be a better option. “N” format adds thousands separators, which also break the number display. “F” does not.Guys, I have changed my culture’s number format to EN without changing the whole culture, on the client side I’m formatting date, number, currency(using JS library). In the backend I return/receive them in EN as below code function in a base controller: public override void OnActionExecuting(ActionExecutingContext context) { SetCultureNumberFormat(); base.OnActionExecuting(context); } private void SetCultureNumberFormat() { if (CultureInfo.CurrentCulture.Name == “ar”) { var cultureInfo = CultureInfo.CurrentCulture.Clone() as CultureInfo; cultureInfo.NumberFormat = CultureInfo.GetCultureInfo(“en-US”).NumberFormat; CultureInfo.CurrentUICulture = CultureInfo.CurrentCulture = cultureInfo; } }
I am having same problem:
I have this Entity:
When I use scaffold Razor Page using Entity Framework (CRUD) and execute the solution I have this html error:
Location in spanish, decimal is comma separated, because html throw this error saying is not a number.
Also, if I use dot decimal separator the database save a number without decimals:
¿This can be related to this issue?
¿How can I solve this issue?
Thanks in advance.
Experiencing the same issue on latest 3.1 stream of .NET Core. I have German culture, so we use “,” as decimal separator. When I send a decimal value from an input field to the controller, the value “214,50” is sent to the controller. But when mapped to my ViewModel in the controller, the comma is lost and the value 21450 in mapped to my models attribute which is a decimal type…
However, with a piece of old legacy code within the same solution, the mapping works just fine although the setup is exactly the same.
EDIT: I just found out that the error only occurs when I use GET. When I send the data via POST, the binding works just fine.