问题
I have an MVC Web-API application for inner use. I have some pages with forms and numeric fields. I need to install this on a German computer, and the users will be only Germans. In Germany they write "3,5" instead of "3.5" (with a comma).
In IIS configuration the culture is "Invariant culture" and since the computer is German - the localize is "de-DE".
When the users write "3,5" in the field - I can see in firebug that "3,5" is what is sent in JSON, but the server gets it as "35".
Can I handle it on server-side? (I don't want to change the json because I'll need to do it in every field and page)
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
public class ItemsController : ApiController, IDisposable
{
[Authorize(Roles = "Admin")]
[HttpPost]
public HttpResponseMessage UpdateItem(ItemViewModel itemVM)
{
// JSON data sent data.NumProp1 = "3,5"
// itemVM.NumProp1 contains "35" instead of "3.5"
}
}
回答1:
You should not localize your JSON - see http://www.json.org for the spec (which only shows the dot as a separator) and How to localize when JSON-serializing? for a similar question.
I wouldn't recommend trying to read your customized JSON - it may sound like a quick win right now, but in the end you simply aren't using JSON.
回答2:
You must use CultureInfo.InvariantCulture on all your string formating calls when handling persitence (and JSON exchanges are technically a form of persitence):
Persisting Data
The InvariantCulture property can be used to persist data in a culture-independent format. This provides a known format that does not change and that can be used to serialize and deserialize data across cultures. After the data is deserialized, it can be formatted appropriately based on the cultural conventions of the current user. For example, if you choose to persist date and time data in string form, you can pass the InvariantCulture object to the
DateTime.ToString(String, IFormatProvider)
orDateTimeOffset.ToString(IFormatProvider)
method to create the string, and you can pass the InvariantCulture object to theDateTime.Parse(String, IFormatProvider)
orDateTimeOffset.Parse(String, IFormatProvider, DateTimeStyles)
method to convert the string back to a date and time value. This technique ensures that the underlying date and time values do not change when the data is read or written by users from different cultures.
This applies to all types: numerics, decimals, floats and doubles, date and time etc. Use the invariant culture both when writing and when reading serialized data. Use invariant culture on both sides of a JSON exchange.
BTW, if you'd use the built-in JSON serializers, you'd already get this lunch for free: JsonWriter.cs, JsonReader.cs.
回答3:
As already said: JSON is a standard, and you should never deviate from the standard. Doing that will make your life miserable.
If the users enter some numbers in a web form, that web form should serialize that in the correct JSON format. I think usually that is done already, if you use the right numeric types in your form, like input type='number'
, etc. On the server end, you should read it using the InvariantCulture.
This need for a general solution is acknowledged by the W3C, as you can see in the draft W3C HTML JSON form submission.
回答4:
In addition to the other answers, if you want to just replace the German "," decimal separator with the current culture one, which makes the conversion parse correctly, use:
str = str.Replace(",", System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator);
You can then convert your string into a numeric value using stuff like Convert.ToInt32
来源:https://stackoverflow.com/questions/28405066/german-culture-get-double-number-from-json-with-a-comma