5 votes

Comment désérialiser une chaîne de caractères en JObject sans notation scientifique en C# ?

J'ai une chaîne de caractères comme celle-ci :

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

Quand je l'analyse en JObject comme ceci

var jObject = JObject.Parse(str);

Mon jObject ressemble à ceci :

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

Je dois me débarrasser de la notation scientifique pour que le JObject résultant ressemble au json original.

J'ai réussi à le faire en utilisant une version ultérieure de Newtonsoft.Json comme ça :

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

Mais j'ai besoin d'obtenir le même résultat en utilisant Newtonsoft.Json version 3.5 qui ne possède pas de propriété FloatParseHandling. Je suppose que je dois implémenter un JsonConverter d'une manière ou d'une autre, mais je n'ai aucune idée de la manière de le faire, puisque mon json réel est beaucoup plus complexe que celui de l'exemple et que je dois gérer toutes les valeurs flottantes de la bonne manière.

Alors, quelle serait la bonne façon d'obtenir un JObject sans notation scientifique pour les valeurs flottantes en utilisant Newtonsoft 3.5 ?

2voto

Jawad Points 9826

Ce qui suit produit l'objet que vous recherchez

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

tiré de ici :

EDIT : Les JTokenTypes dans NewtonSoft v 3.5.8 sont limités à Float et Integer (en ce qui concerne les décimales). Il n'y a pas de type décimal dans cette version et il n'est donc pas possible d'avoir une valeur décimale dans ce JObject.

JTokenTypes de la v3 de 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

La bonne façon de procéder serait de mettre à jour le paquet Newtonsoft :)

1voto

DerAlex23 Points 21

Le code fourni par Jawad n'est pas la meilleure solution car il entraînera des fuites de mémoire. StringReader y JsonTextReader mettent tous deux en œuvre le IDisposable et doivent donc être éliminés s'ils ne sont plus utilisés. Un code plus sûr serait :

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

0voto

Casey Crookston Points 10352

Premièrement, votre json n'est pas valide :) Il devrait avoir des guillemets doubles :

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

Mais encore mieux, en utilisant un boîtier standard, ce serait :

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

Et ensuite, on peut faire ça :

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

val sera alors : "0.00001"

(Note : J'ai volé la solution de : Conversion d'un double en chaîne de caractères sans notation scientifique )

0voto

LP13 Points 4060

Vous pouvez également créer un objet POCO simple. et vous assurer que someProperty est de type string et ensuite désérialiser la chaîne json

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X