简体   繁体   中英

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?

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 :)

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);
        }
    }
}

First, your json isn't valid :) It should have double quotes:

{"data": {"someProperty": 0.00001}}

But even better, using standard casing, would be:

{"Data": {"SomeProperty": 0.00001}}

And then, we can do this:

var str = "{\"Data\": {\"SomeProperty\": 0.00001}}";
dynamic myObject = JsonConvert.DeserializeObject(str);
var val = myObject.Data.SomeProperty.ToString("0." + new string('#', 339));

val will then be: "0.00001"

(Note: I stole the solution from: Double to string conversion without scientific notation )

You can also create simple POCO object. and make sure someProperty is of type string and then de-serialize the json string

var myObject = Newtonsoft.Json.JsonConvert.DeserializeObject<YourObject>(json)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM