Question

La plupart Json parseurs ne sérialisent NaN, car en Javascript, NaN est pas une constante. Json.Net, cependant, ne sérialise valeurs NaN dans NaN, ce qui signifie qu'il délivre en sortie Json invalide; essayant de désérialiser cette Json échouera avec la plupart des parseurs. (Nous sommes désérialisation dans WebKit.)

Nous avons piraté le code Json.Net aux valeurs nulles de sortie lorsqu'il est passé NaN, mais cela semble être une mauvaise solution. Douglas Crockford (une fois) a recommandé d'utiliser nulls en place de Nans:

http://www.json.org/json.ppt (Voir diapositive 16 )

Il est clair que cela ne fonctionnera pas dans tous les cas, mais il serait correct pour nos besoins. Nous aurions tout simplement plutôt de ne pas modifier le code source de Json.Net. Est-ce que quelqu'un sait comment utiliser Json.Net pour convertir les entrées NaN en sorties nulles?

Était-ce utile?

La solution

L'auteur nous conseille « Ecrire un JsonConverter pour flotteur / double pour faire NaN sûr si cela est important pour vous, » afin que ce que vous pouvez faire:

class LawAbidingFloatConverter : JsonConverter {
    public override bool CanRead
    {
        get
        {
            return false;
        }
    }
    public override bool CanWrite
    {
        get
        {
            return true;
        }
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var val = value as double? ?? (double?) (value as float?);
        if (val == null || Double.IsNaN((double)val) || Double.IsInfinity((double)val))
        {
            writer.WriteNull();
            return;
        }
        writer.WriteValue((double)val);
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(double) || objectType == typeof(float);
    }
}

puis l'utiliser:

var settings = new JsonSerializerSettings();
var floatConverter = new LawAbidingFloatConverter();
settings.Converters.Add(floatConverter);
var myConverter = new JsonNetSerializer(settings);

Autres conseils

solution Schweikerts Raphaël avec le soutien de float:

public class StandardFloatConverter : JsonConverter
{
    public override bool CanRead
    {
        get
        {
            return false;
        }
    }
    public override bool CanWrite
    {
        get
        {
            return true;
        }
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        if (value == null)
        {
            writer.WriteNull();
            return;
        }

        var val = Convert.ToDouble(value);
        if(Double.IsNaN(val) || Double.IsInfinity(val))
        {
            writer.WriteNull();
            return;
        }
        // Preserve the type, otherwise values such as 3.14f may suddenly be
        // printed as 3.1400001049041748.
        if (value is float)
            writer.WriteValue((float)value);
        else
            writer.WriteValue((double)value);
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(double) || objectType == typeof(float);
    }
}

Par souci de futurs lecteurs, si des zéros sont acceptables pour vous au lieu de nulls , il semble que cette question a été abordée par Json.Net .

Sérialisation NaN et valeurs en virgule flottante Infinity

Json.NET ne sérialise NaN et l'infini positif et négatif flottante des valeurs de point en tant que symboles, ce qui est JSON valide. Avec 5.0 la nouvelle valeur par défaut est de sérialisation ces valeurs sous forme de chaînes, par exemple "NaN" au lieu de NaN. Il n'y a pas de changement à la sérialisation normale flottante nombre de points.

Un réglage FloatFormatHandling a été ajouté afin que vous puissiez contrôler la façon dont NaN et les valeurs infini sont sérialisés.

string json;     
IList<double> d = new List<double> {1.1, double.NaN, double.PositiveInfinity};

json = JsonConvert.SerializeObject(d);

// [1.1,"NaN","Infinity"]

json = JsonConvert.SerializeObject(d, new JsonSerializerSettings {FloatFormatHandling = FloatFormatHandling.Symbol});  

// [1.1,NaN,Infinity]

json = JsonConvert.SerializeObject(d, new JsonSerializerSettings {FloatFormatHandling = FloatFormatHandling.DefaultValue});  

// [1.1,0.0,0.0]
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top