Search code examples
c#jsonserializationjson.netjsonserializer

Json.Net does not handle deserializing a null DataTable


I have this class as object to serialize:

public class JsonServerToClient
{
    public JsonServerToClient()
    {
        query = new List<Query>();
    }
    public String authKey { get; set; }
    public List<Query> query { get; set; }

    public struct Query
    {
        public int error { get; set; }
        public DataTable result { get; set; }
    }

}

I use JsonConvert.SerializeObject(objectAbove); to serialize JSON.

and JsonConvert.DeserializeObject<JsonServerToClient>(text); to deserialize it.

All works fine when the result is full of data, but if it is null I get this JSON:

{
    "authKey": "pippo",
    "query": [
        {
            "error": -1,
            "result": null
        }
    ]
}

The problem is when I try to deserialize this I get an exception:

Eccezione non gestita di tipo 'Newtonsoft.Json.JsonSerializationException' in Newtonsoft.Json.dll

Ulteriori informazioni: Unexpected end when deserializing array. Path '', line 1, position 56.

Solution

  • UPDATE

    This issue was fixed in Json.Net version 8.0.1. The workaround below is no longer needed.


    It appears that the DataTableConverter that ships with Json.Net (as of v6.0.3) does not handle the case where the data table itself is null. You can work around this issue by subclassing the DataTableConverter and overriding the ReadJson method like this:

    class CustomDataTableConverter : DataTableConverter
    {
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.Null)
            {
                return null;
            }
            return base.ReadJson(reader, objectType, existingValue, serializer);
        }
    }
    

    When you deserialize, be sure to specify the custom converter:

    var obj = JsonConvert.DeserializeObject<JsonServerToClient>(json, 
              new CustomDataTableConverter());