In my Jquery script I post two doubles using the browser's CultureInfo (en-UK) that uses the .
as a fraction separator. My MVC app is running on a server with locale nl-BE using the ,
as a fraction separator.
[AcceptVerbs(HttpVerbs.Post)]
public JsonResult GetGridCell(double longitude, double latitude)
{
var cell = new GridCellViewModel { X = (int)Math.Round(longitude, 0), Y = (int)Math.Round(latitude, 0) };
return Json(cell);
}
The modelbinding fails because of the parsing issue.
I think it would be best to have my javascript set to en-UK and the same for the modelbinding in my MVC app. But I don't know how to do either.
Any suggestions?
ModelBinding uses CurrentCulture to parse values. Thats understandable, because the user might enter a date or decimal into a textbox and the value would be parsed correctly.
But I still think most developers see it the way you see it: They want that all values are parsed by using the same culture no matter what language the user uses. They want to display values in the format of the user but enter values in a neutral format (InvariantCulture).
Thats why I set the CurrentCulture in Application.BeginRequest to CultureInfo.InvariantCulture. By that all Binding uses the invariant Culture. If you later want to use Ressources or format values in the language of the browser you have to switch back to the language of the user, by setting CurrentCulture to the language of the user again. I do this in an action filter.
EDIT:
The OP corrected me in that only Form submissions are culture aware: thats true. See the source for ValueProviderDictionary:PopulateDictionary where it is documented:
I'm not sure how far localisation goes with the default model binder (DefaultModelBinder), but you can easily create a binder yourself that can handle the culture specific parsing of the data, e.g, create a new class, let's call it the DoubleModelBinder, copypasta the following:
Now, what we are doing here, is establishing our own language-aware double-parser. When we implement the IModelBinder interface, we need to create a BindModel method. This is where the meat of the it is done, but before we can parse anything, we need to get an IFormatProvider based on the browser's language. So, we use the GetUserCulture method to try and ready the browser's language. If we can't revert to the current culture.
When we have that, we are then in a position to parse the value. We first grab it from the ValueProvider (which is really a composite of many value providers, e.g. from the Form collection, Request collection, etc.), and then we parse it using the discovered IFormatProvider, which is the CultureInfo we now have.
Once you've done that, it's pretty trivial to add it to the model binder collection;
Try that and see if that helps.