Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serialize NaN values into JSON as nulls in JSON.NET

Most Json parsers don't serialize NaN, because in Javascript, NaN is not a constant. Json.Net, however, does serialize NaN values into NaN, which means it outputs invalid Json; attempting to deserialize this Json will fail with most parsers. (We're deserializing in WebKit.)

We have hacked the Json.Net code to output null values when passed NaN, but this seems like a poor solution. Douglas Crockford (once) recommended using nulls in place of NaNs:

http://www.json.org/json.ppt (Look at slide 16)

Clearly this won't work in all cases, but it would be ok for our purposes. We'd just rather not have to modify the source code of Json.Net. Does anyone know how to use Json.Net to convert NaN inputs into null outputs?

like image 508
ACK_stoverflow Avatar asked Oct 18 '11 21:10

ACK_stoverflow


People also ask

Can JSON serialize null?

Apparently nulls are automatically serialized directly into null , without the custom pipeline. Stepping through this in the debugger, I noted that neither of these methods are called for properties that have a null value. Delving into JSON.

What is Jsonconvert DeserializeObject?

DeserializeObject<T>(String,JsonConverter[]) Deserializes the JSON to the specified . NET type using a collection of JsonConverter. DeserializeObject(String, JsonSerializerSettings) Deserializes the JSON to a .

What is Jsonconvert SerializeObject C#?

SerializeObject Method (Object, Type, JsonSerializerSettings) Serializes the specified object to a JSON string using a type, formatting and JsonSerializerSettings.

What is JsonSerializerSettings?

Specifies the settings on a JsonSerializer object.


1 Answers

The author advises us to “Write a JsonConverter for float/double to make NaN safe if this is important for you,” so that’s what you can do:

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

and then use it:

var settings = new JsonSerializerSettings();
var floatConverter = new LawAbidingFloatConverter();
settings.Converters.Add(floatConverter);
var myConverter = new JsonNetSerializer(settings);
like image 135
Raphael Schweikert Avatar answered Sep 16 '22 16:09

Raphael Schweikert