This project is read-only.

Troubles with NumericInputFor() for decimals when using non-english culture

Jan 18, 2015 at 6:24 PM
Edited Jan 20, 2015 at 6:50 AM
Hi all,

In my application, I set Thread.CurrentThread.CurrentCulture and CurrentUICulture to user's preferred language. This is done in overriden BeginExecuteCore() method.

In the layout page, I've
<html lang="@System.Globalization.CultureInfo.CurrentCulture.Name" xmlns="http://www.w3.org/1999/xhtml" xml:lang="@System.Globalization.CultureInfo.CurrentCulture.Name">
 <script type="text/javascript">
  Globalize.culture("@System.Globalization.CultureInfo.CurrentCulture.Name");
  </script>
A model contains decimal property I render in a view using helper
  @Html.InputNumberFor(m => m.Split.LowCountLevel, new { Step = "any" })
When user has choosen en culture (using dot as decimal separator) everything works OK.
But when I choose cs (czech, which uses comma as decimal separator), no value is shown at all i.e. input element is empty and in the underlying HTML code, the attribute value contains comma e.g. value="15,00". And I'm not able to enter any decimal number, either with dot nor comma as decimal separator.

What I've missed when I implemented globalization?
Jan 20, 2015 at 2:32 PM
Edited Jan 20, 2015 at 2:33 PM
I digged around the plain html input widget:
  1. according W3 specs, the decimal floating point number as value attribute must be rendered using dot as decimal separator http://www.w3.org/TR/html-markup/datatypes.html#common.data.float. To achieve this, I render value as follows
<input type="number" value="@(Model.DecimalValue.ToString(new CultureInfo("en"))) />
  1. Browser itself follows culture in <HTML lang="xx" ...> attribute to accept specific decimal separator
  2. Browser emits a floating point number formatted as at point 1) i.e. using dot as decimal separator, but Mvc model binder is culture dependend, hence it fails for non-english cultures. The solution is a custom decimal binder. I've used this one
Coordinator
Jan 20, 2015 at 4:09 PM
It is a well known problem. The simplest way to solve it is by setting the invariant culture as Thread culture. Then you may use a different uiCulture, (that is as the culture to access language dependent resource files). The drawback of a similar solution is that if you use not Html5 inputs they are not globalized properly. Thus this solution is viable only if all numbers and date are rendered with Html5 inputs.

In the next release of this toolkit I will define a ToCultureInvariant helper that serialize any type by using the InvariantCulture, and when the form is submitted forces the ModelBinder to use InvariantCulture for binding, This helper should solve all problems with Html5 inputs. In the next days I'll implement this feature, so if you want I cand send you the pre-release dlls, that contain also a few other improvements.

If you are interested send me a message with the contact form of my blog, and when ready I will send the dlls to the email addess declared in the contact form (avoid putting your email here...because of smamming robots): http://www.dotnet-programming.com/contact.aspx