Search code examples
c#arraysjsonjson.netdeserialization

Why does Newtonsoft JsonConvert not deserialize Json array fields?


I am fetching a Json object which has a Details field that is an array of Detail objects, for example:

"details":"[{\"field_id\":\"1142488407\",\"response\":\"256\",\"field_type\":\"text\"},{\"field_id\":\"72403497\",\"response\":\"\",\"field_type\":\"text\"},{\"field_id\":\"845605582\",\"response\":\"Michael\",\"field_type\":\"text\"},{\"field_id\":\"987024660\",\"response\":\"157\",\"field_type\":\"dropdown\"}]"

The model I have for the Details field is:

[JsonProperty("details")]
public List<LogDetailModel> DetailModels { get; set; }

And the Detail object model is:

[JsonProperty("field_id")]
public string EditedFieldId { get; set; }

[JsonProperty("response")]
public string Response { get; set; }

[JsonProperty("field_type")]
public string FieldType { get; set; }

However, when I try to deserialize the results (an array of my base model), I get the following:

JsonSerializationException: Error converting value "[{"field_id":"1142488407","response":"256","field_type":"text"},{"field_id":"72403497","response":"","field_type":"text"},{"field_id":"845605582","response":"Michael","field_type":"text"},{"field_id":"987024660","response":"157","field_type":"dropdown"}]" to type 'System.Collections.Generic.List`1[KolHalev.Business.Breeze.Models.LogDetailModel]'. Path '[0].details', line 1, position 423.

And if I instead fetch that field as a string, and then deserialize thusly:

[JsonProperty("details")]
public string Details { get; set; }
public List<LogDetailModel> DetailModels { get { return JsonConvert.DeserializeObject<List<LogDetailModel>>(Details); }  }

This works fine. What am I missing?


Solution

  • The reason why you could not deserialize it directly is because your json and your data model has a mismatch.

    "details":"[{\"field_id\":\"1142488407\",\"response\":\"256\",\"field_type\":\"text\"},..]"
    
    • In this case your details data type is string
    • So, you can NOT parse it directly as a collection of objects

    if your json would look like this:

    "details":[{\"field_id\":\"1142488407\",\"response\":\"256\",\"field_type\":\"text\"},..]
    
    • the the data type of the details field would be a collection

    So, the very reason why did your second approach worked is because you have first deserialized the details then you deserialized the json array.