1

I have a class with an object property, if i create this class with a decimal value for the property and serialize it, that value looks fine:

var testObject = new TestObject{
    TestDecimal = 8801203167395152041.7m
};
var serialized = Newtonsoft.Json.JsonConvert.SerializeObject(testObject);
serialized.Dump(); // returns {"TestDecimal":8801203167395152041.7}

However, if i try to deserialize this using a jtoken, the value becomes a scientific value and saved as a double, here is the entire code:

void Main()
{

    var testObject = new TestObject{
        TestDecimal = 8801203167395152041.7m
    };
    var serialized = Newtonsoft.Json.JsonConvert.SerializeObject(testObject);

    serialized.Dump();
    TestObject result = JsonConvert.DeserializeObject<TestObject>(serialized, new JsonSerializerSettings
    {
        Converters = new List<JsonConverter> { new TestDesiralizer() }
    });
    testObject.TestDecimal.Dump();
    result.TestDecimal.Dump();

}

public class TestObject{
    public object TestDecimal { get; set; }
}

public class TestDesiralizer : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(TestObject);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        serializer.Culture = CultureInfo.InvariantCulture;
        reader.Culture = CultureInfo.InvariantCulture;
        JToken token = serializer.Deserialize<JToken>(reader);
        TestObject obj = token.ToObject<TestObject>();
        obj.TestDecimal =  decimal.Parse(Convert.ToString(obj.TestDecimal,CultureInfo.InvariantCulture) ?? "",NumberStyles.Any, CultureInfo.InvariantCulture);
        return obj;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

This results in:

1) 8801203167395152041,7

2) 8801203167395150000

How do i keep the decimal value when deserializing the json?

Jonas Olesen
  • 568
  • 5
  • 25
  • Ye, this is a simplified example, the real code can handle other types as well in the property – Jonas Olesen Aug 28 '19 at 08:13
  • 3
    I think you need to temporarily set `reader.FloatParseHandling = FloatParseHandling.Decimal` before the call to `serializer.Deserialize(reader);`. See: [JObject.Parse modifies end of floating point values](https://stackoverflow.com/a/26488559/3744182). – dbc Aug 28 '19 at 08:16
  • Ah yes, that seems to solve it, cheers – Jonas Olesen Aug 28 '19 at 08:17

1 Answers1

1

As per Dbc's comment, setting the following during the deserializing seems to solve the issue:

reader.FloatParseHandling = FloatParseHandling.Decimal
ProgrammingLlama
  • 36,677
  • 7
  • 67
  • 86
Jonas Olesen
  • 568
  • 5
  • 25