0

I need a way for JSON.Net to always deserialize a property as an array and if it is an object to wrap it in an array. I cannot control how the property is returned (object or list of objects) but basically if there is only one it returns an object, if there is more than one it returns a list.

Exception message:

Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[Blah.Attachment]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly. To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.

// "attachment" property as object
{
    "issues": [
        {
            // ...
            "attachments": {
                "attachment": {
                    "id": "13419",
                    // ... other properties
                }
            }
        }
    ]
}

// "attachment" property as list of objects
{
    "issues": [
        {
            // ... other properties
            "attachments": {
                "attachment": [
                    {
                        "id": "13419",
                        // ... other properties
                    },
                    {
                        "id": "1278",
                        // ... other properties
                    },
                    // ... more of them
            }
        }
    ]
}

This json is actually embedded a few levels deep in a much larger structure. All the examples I've seen that use a custom JsonConverter assume you're converting the top level object so I haven't found those useful.

This is an example of the class structure I'm trying to deserialize into (again, the real version is much larger):

class Root {
    [JsonProperty("issues")]
    public List<Issue> Issues { get; set; }
}

class Issue {
    // ... other properties

    [JsonProperty("attachments")]
    public AttachmentsList Attachments { get; set; }
}

class AttachmentsList {
    [JsonProperty("attachment")]
    public List<Attachment> All { get; set; }
}

class Attachment {
    [JsonProperty("id")]
    public int Id { get; set; }

    // ... other properties
}

This is the line of code that fails once it finds an object instead of an array:

var root = JsonConvert.DeserializeObject<Root>(json);

How can I force it wrap the object in an array when the property is an object? Is there a JSON.Net Attribute I am unware of or something? Is this possible (because this is what I have to deal with)? I need it to always be an array.

Edit: @BrianRogers found the answer to my question that I've been looking for for hours: How to handle both a single item and an array for the same property using JSON.net

Andy Hubbard
  • 118
  • 8
  • You can write your own `JsonConverter` or use `Json.Linq` – Pavel Anikhouski Oct 21 '20 at 16:08
  • 1
    You can use the `SingleOrArrayConverter` class from [How to handle both a single item and an array for the same property using JSON.net](https://stackoverflow.com/q/18994685/10263) to solve this. Place a `[JsonConverter(typeof(SingleOrArrayConverter))]` attribute on the `All` property in your `AttachmentsList` class. In fact I think this is a duplicate question. Would you agree? – Brian Rogers Oct 21 '20 at 16:10
  • @BrianRogers Thank you, that works perfectly! I was looking for it for hours, guess my google-fu was weak today. Feel free to mark it as duplicate so people who stumble on this question are pointed right to the answer :) – Andy Hubbard Oct 21 '20 at 16:24
  • Done. Glad it worked for you! – Brian Rogers Oct 21 '20 at 16:25

0 Answers0