Andrew Andrew - 3 months ago 90
C# Question

Json.NET Decimal Parsing Rounding

Why does the single decimal get rounded but the decimals in the array do not?

JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
FloatParseHandling = FloatParseHandling.Decimal,
Culture = new CultureInfo(string.Empty)
{
NumberFormat = new NumberFormatInfo
{
CurrencyDecimalDigits = 5
}
}
};

string jsonData = "{\"Values\": [0.0,22493194440943108.0]}";
JObject jObject = JObject.Parse(jsonData);
decimal[] arrayOfDecimals = JsonConvert.DeserializeObject<decimal[]>(jObject["Values"].ToString());
decimal singleDecimal = JsonConvert.DeserializeObject<decimal>(jObject["Values"][1].ToString());

Console.WriteLine(JsonConvert.DeserializeObject<decimal[]>(jObject["Values"].ToString())[1]);
Console.WriteLine(JsonConvert.DeserializeObject<decimal>(jObject["Values"][1].ToString()));


Output is :

22493194440943108.0

22493194440943100

Answer

When you call the ToString() method, Json.NET will create a formatted string of the values it contains. That means for jObject["Values"].ToString(), you get:

[
  0.0,
  22493194440943108.0
]

And for jObject["Values"][1].ToString(), you get:

2.24931944409431E+16

Deserialising these works, but you can see that the formatting of the singular one has resulted in some rounding. If you really do want to call ToString then deserialise something you've already deserialised (using JObject.Parse), you can pass the Formatting.None option - this works as expected:

decimal[] arrayOfDecimals = JsonConvert.DeserializeObject<decimal[]>(jObject["Values"].ToString(Newtonsoft.Json.Formatting.None));
decimal singleDecimal = JsonConvert.DeserializeObject<decimal>(jObject["Values"][1].ToString(Newtonsoft.Json.Formatting.None));