Newtonsoft.json: A string that looks like a date is changed when deserializing an ISerializable object

Created on 9 May 2016  路  6Comments  路  Source: JamesNK/Newtonsoft.Json

I have an object with a string property that happens to have a value that looks like an XML datetime. I serialize it using JsonConvert.SerializeObject() and deserialize it back using JsonConvert.DeserializeObject(). Normally this works fine. However, if the object implements ISerializable then during deserialization a different value is returned from info.GetString().

It appears that JSON.NET takes it upon itself to parse my string as a date and then convert the date back to a string. The behaviour should not differ based on implementing ISerializable or not. (Actually, I think it should not do this automatic conversion at all, ever, but this is already covered by #862)

The following code reproduces the problem. It can be run as a LINQPad snippet.

// Works if you comment out the ISerializable implementation, but with it AsString deserializes as "05/09/2016 12:34:56"
class MySerializable : ISerializable
{
    public MySerializable()
    {
    }

    protected MySerializable(SerializationInfo info, StreamingContext context)
    {
        AsString = info.GetString("AsString");
    }

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("AsString", AsString);
    }

    public string AsString
    {
        get; set;
    }
}

void Main()
{
    var original = new MySerializable { AsString = "2016-05-09T12:34:56" };

    var json = JsonConvert.SerializeObject(original);
    var fromJson = JsonConvert.DeserializeObject<MySerializable>(json);

    if (fromJson.AsString != original.AsString)
        throw new ApplicationException("Mismatch! Deserialized as " + fromJson.AsString);
}

Most helpful comment

Please fix this issue. We get that you like how it works, but your solution to just use DateParseHandling.None doesn't work when the issue is caused within compiled libraries that "inherit" the dependency on a particular version of Newtonsoft.Json because of another Nuget package in the same project.

Having a non-standard default _does_ cause breaking changes that are not always able to be fixed by your suggested workaround. There are libraries I can't use in a current project because they would advance the Newtonsoft.Json version to the most recent build, which contains this issue, breaking other pre-compiled libraries used by the same project.

All 6 comments

You can disable this behavior by setting the DateParseHandling property of the serializer settings to None. IMO, this should be the default...

Agreed, it should by default not do this, but that's already covered by #862. This issue is about inconsistent behaviour when DateParseHandling is left at its default value.

You can disable this behavior by setting the DateParseHandling property of the serializer settings to None. IMO, this should be the default...

Scratch that. It doesn't seem to have any effect. JObject.ToObject<T>() always seems to parse the string as a date, and JsonConvert.DeserializeObject<T> never does (at least that's what I observed)

Whether a date is a string or not is determined when loading the JObject, not when converting it to a strongly typed object.

I faced this same issue. Setting DateParseHandling.None fixes it, but there's no excuse to force-enable an incompatible extension to the standard. JSON.NET isn't a JSON parser if it doesn't parse JSON according to the standard: it's a NewtonsoftObjectNotation parser.

Please fix this issue. We get that you like how it works, but your solution to just use DateParseHandling.None doesn't work when the issue is caused within compiled libraries that "inherit" the dependency on a particular version of Newtonsoft.Json because of another Nuget package in the same project.

Having a non-standard default _does_ cause breaking changes that are not always able to be fixed by your suggested workaround. There are libraries I can't use in a current project because they would advance the Newtonsoft.Json version to the most recent build, which contains this issue, breaking other pre-compiled libraries used by the same project.

Was this page helpful?
0 / 5 - 0 ratings