Search code examples
c#jsonjson.netjson-deserialization

Deserialise JSON Object


I have a json object that looks like this:

[
    {"attributes": []},
    {"attribute_values": []},
    {"digital_assets": []},
    {"products": []},
]

So I thought if I created the following c# class, I could deserialise straight into it using newtonsofts JsonConvert.Deserialize<ProductContainer>():

public class ProductContainer
{
    [JsonProperty(PropertyName = "attributes")]
    public AttributeEntity[] Attributes { get; set; }

    [JsonProperty(PropertyName = "attribute_values")]
    public AttributeValueEntity[] AttributeValues { get; set; }

    [JsonProperty(PropertyName = "digital_assets")]
    public DigitalAssetEntity[] DigitalAssets { get; set; }

    [JsonProperty(PropertyName = "products")]
    public ProductEntity[] Products { get; set; }
}

However, I get the following error:

Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'ProductContainer' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly. To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array. Path '', line 1, position 1.

I think it may be because my JSON is in the incorrect format. What am I meant to change in order for this to work properly (either in the JSON file or in the C# class)


Solution

  • As you can see in your Json string it is an array of objects.
    I described difference between those in this answer.

    Problem is that yours contains a Dictionary type that contains string as a key and an array as a value.

    In your case :

    [
        {"attributes": []},
        {"attribute_values": []},
        {"digital_assets": []},
        {"products": []},
    ]
    

    You have to first deserialize this to let's say JObject[] or List<JObject> :

    var objects = JsonConvert.Deserialize<List<JObject>>();
    

    Then process each of these objects and find out the key value and assign the values or you can just change the first and last character of your Json object :

    string newJsonString = "{" + oldJsonString.Substring(1, oldJsonString.Length - 2) + "}";
    

    Which will return :

    {
        {"attributes": []},
        {"attribute_values": []},
        {"digital_assets": []},
        {"products": []},
    }
    

    small remark here
    This will still return an object which contains a key and value pair where the key is of type string and value is and array of something. But using the second method you can deserialize it using JsonConvert.Deserialize<Dictionary<string, JObject>>(); and then deserialize each of these objects to correct type eg.:

    var dictionaryResult = JsonConvert.Deserialize<Dictionary<string, JObject>>();
    meResultObject.Attributes = JsonConvert.Deserialize<List<AttributeEntity>>(dictionaryResult["attributes"].ToString());