question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Serialization of decimals does not respect precision

See original GitHub issue

Problem

C# decimal value serialized to JSON and de-serialized back to decimal gives a number with different precision.

Explanation

Decimals in .NET are tricky: besides the number itself, they store the number of digits necessary to represent it. For example, numbers 15 and 15.0 stored in decimal variable will be represented differently in memory, though considered equal in comparison. When we serialize and de-serialize numbers, it is important to keep this information.

Steps to reproduce

using Newtonsoft.Json;
using System;

namespace JsonDecimalIssue
{
    class Program
    {
        static void Main(string[] args)
        {
            decimal before = 15;
            string serialized = JsonConvert.SerializeObject(before); // produces "15.0" <- incorrect
            decimal after = JsonConvert.DeserializeObject<decimal>(serialized);

            Console.WriteLine(before); // Writes "15"
            Console.WriteLine(after);  // Writes "15.0"
            Console.ReadKey();
        }
    }
}

Possible solution

The issue can be solved by keeping the necessary number of decimal digits in JSON representation of the number, e.g. serialize decimal 15 as integer “15”, and decimal 15.0 as “15.0”. This is exactly how Decimal.ToString() works. Then the number of digits can be respected when de-serializing back to decimal.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:11
  • Comments:12 (3 by maintainers)

github_iconTop GitHub Comments

30reactions
JamesNKcommented, May 29, 2018

That is expected behavior. Json.NET always serializes floats and decimals with a decimal point.

You could write a JsonConverter for decimal and write it without the trailing .0

20reactions
stijnherremancommented, Jul 23, 2018

I agree that this is unexpected behaviour at the very least, and imho it is also a bug. For 15, the precision is 2 and the scale is 0. For 15.0, the precision is 3 and the scale is 1. They’re two different things.

I wholly understand that this could be a major breaking change, but can you please reconsider it?

Read more comments on GitHub >

github_iconTop Results From Across the Web

c# - Json.Net not serializing decimals the same way twice
The objects appear to be identical to the original after deserializing either JSON string, but I want to be sure there isn't something...
Read more >
Json serialization gone wrong
Serialization respects your data (well, almost) and keeps number of decimal spaces. So the value gets serialized as is: 385.0000000000004. ...
Read more >
JsonUtility serializes floats with way too many digits
For this i want to use the build in JsonUtility. But JsonUtility converts a Vector3 to floats with a lot of decimal places....
Read more >
Decimal Struct (System)
Conversions from Decimal to Single or Double are narrowing conversions that might lose precision but not information about the magnitude of the converted...
Read more >
Newtonsoft Json Serialize String Array
NullValueHandling Serialization of decimals does not respect precision #1726. Basic Serialization Serialization is the process of converting an object into ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found