[CSHARP-4791] Driver unable to deserialise valid decimal values Created: 18/Sep/23  Updated: 26/Sep/23  Resolved: 26/Sep/23

Status: Closed
Project: C# Driver
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Unknown
Reporter: Rhys Bevilaqua Assignee: Oleksandr Poliakov
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Documentation Changes Summary:

1. What would you like to communicate to the user about this feature?
2. Would you like the user to see examples of the syntax and/or executable code and its output?
3. Which versions of the driver/connector does this apply to?


 Description   

Summary

When deserialising certain valid numbers to System.Decimal (e.g. 9.300000190734863 ) an exception of MongoDB.Bson.TruncationException is thrown

Please provide the version of the driver. If applicable, please provide the MongoDB server version and topology (standalone, replica set, or sharded cluster).

Assembly: MongoDB.Bson, Version=2.21.0.0, Culture=neutral, PublicKeyToken=null

How to Reproduce

Here's some sample code that should work just fine but does not:

public class MyDocumentType {
   public decimal Number {get;set;}
}
 
public static void Main() {
    var validDecimalString = "9.300000190734863";
    var validDecimal = Decimal.Parse(validDecimalString);
    Console.WriteLine(validDecimalString + " --> " + validDecimal);
    Console.WriteLine();
 
    var myValidDecimalJson = "{\"Number\": 9.300000190734863 }";
    try 
    {
        var obj = BsonSerializer.Deserialize<MyDocumentType>(myValidDecimalJson);
        Console.WriteLine(myValidDecimalJson + " --> " + obj.Number);
    }
    catch (Exception e)
    {
        Console.WriteLine(myValidDecimalJson + " ---> " + e.GetType().Name + ": " + e.Message);
    }
 
 
//Sample output:
// 9.300000190734863 --> 9.300000190734863
//
// {"Number": 9.300000190734863 } ---> FormatException: An error occurred while deserializing the Number property of class VetDB.Tests.My.SampleDeserialisations+MyDocumentType: Truncation resulted in data loss.
 

Additional Background

Please provide any additional background information that may be helpful in diagnosing the bug.



 Comments   
Comment by Oleksandr Poliakov [ 26/Sep/23 ]

Hi rhys.bevilaqua@vetdb.com 

The root cause of the problem is the fact that MongoDB uses Double as default floating point data type. It means your example is a little more complex then just parsing decimal. DecimalSerializer doing the following operations:
1) Check the value BsonType: it's Double as I've mentioned above.
2) Reads the value as Double and got 9.3000001907348633
3) Converts it to decimal and got 9.30000019073486

As the result serializer detects that converted result was truncated with comparing to the originally read data and throw the exception.

To make it work more predictable you can choose one of the following:
1) Change your model to use Double
2) Represent your decimal as a string or Decimal128 in MongoDB:
  "{Number: '9.300000190734863' }" - decimal is represented as a string, please note there are quotes
  "{Number: NumberDecimal('9.300000190734863') }" - decimal is represented as Decimal128.
3) Assign BsonRepresentation attribute onto the property and allow data truncation:

  [BsonRepresentation(BsonType.Double, AllowTruncation = true)]

I hope this makes sense.

I'll close the ticket, but feel free to reopen it if you have more questions related to the problem or will require further assistance.

Comment by PM Bot [ 18/Sep/23 ]

Hi rhys.bevilaqua@vetdb.com, thank you for reporting this issue! The team will look into it and get back to you soon.

Generated at Wed Feb 07 21:49:22 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.