Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deserializing an array of different object types

Tags:

c#

json.net

Using the Json.NET library, I'm having trouble deserializing some json returned as an array. The json is an array containing some paging information as an object and array of country objects. Here's a sample of the returned json:

[
    {
        "page": 1,
        "pages": 6,
        "per_page": "50",
        "total": 262
    },
    [
        {
            "id": "ABW",
            "iso2Code": "AW",
            "name": "Aruba",
            "region": {
                "id": "LCN",
                "value": "Latin America & Caribbean (all income levels)"
            },
            "adminregion": {
                "id": "",
                "value": ""
            },
            "incomeLevel": {
                "id": "NOC",
                "value": "High income: nonOECD"
            },
            "lendingType": {
                "id": "LNX",
                "value": "Not classified"
            },
            "capitalCity": "Oranjestad",
            "longitude": "-70.0167",
            "latitude": "12.5167"
        }
    ]
]

I am attempting to deserialize to the following types:

class CountriesQueryResults
{
    public PagingInfo PageInfo { get; set; }
    public List<CountryInfo> Countries { get; set; }
}

class PagingInfo
{
    public int Page { get; set; }
    public int Pages { get; set; }
    [JsonProperty("per_page")]  
    public int ResultsPerPage { get; set; }
    public int Total { get; set; }
}

class CountryInfo
{
    public string Id { get; set; }
    public string Iso2Code { get; set; }
    public string Name { get; set; }
    public string Longitude { get; set; }
    public string Latitude { get; set; }
    public string CapitalCity { get; set; }
    public CompactIdentifier Region { get; set; }
    public CompactIdentifier AdminRegion { get; set; }
    public CompactIdentifier IncomeLevel { get; set; }
    public CompactIdentifier LendingType { get; set; }  
}

class CompactIdentifier
{
    public string Id { get; set; }
    public string Value { get; set; }
}

I am calling DeserializeObject as so:

var data = JsonConvert.DeserializeObject<List<CountriesQueryResults>>(response);

I am getting the following error:

Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'CountriesQueryResults' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.

I have been trying to get the answer from the documentation but I can't seem to figure it out. Any help would be appreciated.

like image 706
Sleette Avatar asked Feb 14 '15 20:02

Sleette


People also ask

Is JSON serialized or Deserialized?

JSON is a format that encodes objects in a string. Serialization means to convert an object into that string, and deserialization is its inverse operation (convert string -> object). If you serialize this result it will generate a text with the structure and the record returned.

Can t deserialize JSON array into?

bind. JsonbException: Can't deserialize JSON array into: class exception occurs when you try to convert json string data to a java object. If the json string contains an array of objects and attempts to deserialize the json string to a json object, the array of objects could not be assigned to a single java object.


1 Answers

Since your json is like this [ {....} , [{....}] ], You can only deserialize it to an object array(Where first item is an object and second, another array).

This simplest way I think to convert it to a c# object is:

var jArr = JArray.Parse(jsonstr);
var pageInfo = jArr[0].ToObject<PagingInfo>();
var countryInfos = jArr[1].ToObject<List<CountryInfo>>();

Class definitions would be:

public class PagingInfo
{
    public int page { get; set; }
    public int pages { get; set; }
    [JsonProperty("per_page")]
    public int ResultsPerPage { get; set; }
    public int total { get; set; }
}

public class Region
{
    public string id { get; set; }
    public string value { get; set; }
}

public class AdminRegion
{
    public string id { get; set; }
    public string value { get; set; }
}

public class IncomeLevel
{
    public string id { get; set; }
    public string value { get; set; }
}

public class LendingType
{
    public string id { get; set; }
    public string value { get; set; }
}

public class CountryInfo
{
    public string id { get; set; }
    public string iso2Code { get; set; }
    public string name { get; set; }
    public Region region { get; set; }
    public AdminRegion adminregion { get; set; }
    public IncomeLevel incomeLevel { get; set; }
    public LendingType lendingType { get; set; }
    public string capitalCity { get; set; }
    public string longitude { get; set; }
    public string latitude { get; set; }
}

PS: You can change the property names' first char to Uppercase if you want. I used http://json2csharp.com/ to automatically generate those classes.

like image 104
EZI Avatar answered Sep 23 '22 00:09

EZI