Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to deserialize string to JObject without scientific notation in C#

I have a string like this:

var str = "{'data': {'someProperty': 0.00001}}";

When I parse it to JObject like that

var jObject = JObject.Parse(str);

My jObject looks like this:

{"data": {"someProperty": 1E-05}}

I need to get rid of scientific notation so that resulting JObject would look like original json.

I managed to do that using later version of Newtonsoft.Json like that:

var serializer = new JsonSerializer { FloatParseHandling = FloatParseHandling.Decimal };
using (System.IO.TextReader tr = new System.IO.StringReader(str)
using (var jsonReader = new JsonTextReader(tr))
{
    var jp = serializer.Deserialize(jsonReader);
    var jObject = JObject.FromObject(jp);
}

But I need to achieve the same result using Newtonsoft.Json version 3.5 which does not have a FloatParseHandling property. I guess I need to implement a JsonConverter somehow, but I have no idea how to do that, since my real json is much more complex than the one in example and I need to handle all the float values in it the right way.

So, what would be the right way to get a JObject without a scientific notation for float values using Newtonsoft 3.5?

like image 331
Илья Иваницкий Avatar asked Oct 16 '22 08:10

Илья Иваницкий


2 Answers

Following produces the object you are looking for

JObject.Load(new JsonTextReader(new StringReader(str)) { FloatParseHandling = FloatParseHandling.Decimal }, null)

taken from here:

EDIT: JTokenTypes in NewtonSoft v 3.5.8 are limited to Float and Integer (in regards to decimal). There is no decimal type in that version and thus makes it not possilbe to have a decimal value in that JObject.

JTokenTypes from v3 of newtonsoft

    None = 0,
    Object = 1,
    Array = 2,
    Constructor = 3,
    Property = 4,
    Comment = 5,
    Integer = 6,
    Float = 7,
    String = 8,
    Boolean = 9,
    Null = 10,
    Undefined = 11,
    Date = 12,
    Raw = 13,
    Bytes = 14

The right way to do this would be to upgrade the Newtonsoft package :)

like image 89
Jawad Avatar answered Nov 01 '22 10:11

Jawad


Jawad's provided code is not the best solution because it will end up in memory leaks. StringReader and JsonTextReader are both implementing the IDisposable interface and therefore must be disposed if they are not used anmyore. Safer code would be:

public JObject CustomJObjectLoad(string str)
{
    using (var stringReader = new StringReader(str))
    {
        using (var jsonReader = new JsonTextReader(stringReader) { FloatParseHandling = FloatParseHandling.Decimal })
        {
            return JObject.Load(jsonReader, null);
        }
    }
}
like image 44
DerAlex23 Avatar answered Nov 01 '22 08:11

DerAlex23