Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WebAPI, JSON.Net and losing decimal precision

I've come across a bit of a strange issue using WebAPI and JSON.Net. When de-serialising JSON that has been submitted to my API I seem to be losing precision! I'm submitting the decimal to 3 decimal places, but when the values materialises in my object it's only to 2 decimal places!

The JSON I submit looks like this:

{
    id: 1,
    name: 'mock data',
    value: 123.456
}

This is bound to a class that looks something like this:

public class MockObject {
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Value { get; set; }
}

Just for completeness this is basically what my WebAPI method looks like:

public HttpResponseMessage Post (MockObject data) {
    // do something with the value here and return the relevant response
}

I'm submitting the data via a JQuery ajax request, but I can see the posted values are exactly as I expect when inspecting the values in the chrome dev tools before submitting and in fiddler once they've gone "over the wire".

When it gets to doing something with the materialised object in the Post method the value of "Value" is 123.45.

If I submit 2 or fewer decimal places (i.e. 123.4 or 123.45) the value gets de-serialised as expected, however if I submit more than 2 decimal places (i.e. 123.456 or 123.4567 etc the value is always getting de-serialised to 123.45.

Anyone else come across this issue? Any suggestions?

like image 448
Mo D Avatar asked Jul 25 '13 10:07

Mo D


1 Answers

I managed to sort this out.

In the end the problem was being caused by the fact that the culture was being set which contains currency number formatting. The currency number format specifies the number of decimal places which should be used for decimal values.

To fix this I now set the WebApi JSON serializer culture to a new instance of CultureInfo.InvariantCulture in Global.ascx.cs like so:

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.Culture = new CultureInfo(string.Empty) {
    NumberFormat = new NumberFormatInfo {
        CurrencyDecimalDigits = 5
    }
};

This means that decimal values can have anything up to 5 decimal places.

like image 90
Mo D Avatar answered Oct 13 '22 00:10

Mo D