Kevin Ferreira
Kevin Ferreira

Reputation: 65

Deserialize Json to List C#

I'm having some issues on deserializing a Json that the api returns.

The Json is the following:

{ "Result":[
    {
        "Id": 1, 
        "Type": "Type1"
    },
    {
        "Id": 2, 
        "Type": "Type2"
    }
]}

I'm trying to deserialize it to a list of this type:

public class ContactType
{
    public int Id { get; set; }
    public string Type { get; set; }
}

The ReturnType used below is: List<ContactType> and the function GetContactTypes<ReturnType> is called this way:

var test = await _items.GetContactTypes<List<ContactType>>(AuthToken.access_token);

Using this code:

    public async Task<ReturnType> GetContactTypes<ReturnType>(string access_token)
    {
        try
        {
            Header = string.Format("Bearer {0}", access_token);
            client.DefaultRequestHeaders.Add("Authorization", Header);

            HttpResponseMessage response = await client.GetAsync(base_url + "contacttypes");

            if (response.StatusCode == HttpStatusCode.OK)
            {
                return JsonConvert.DeserializeObject<ReturnType>(await response.Content.ReadAsStringAsync());
            }
            else
            {
                return default(ReturnType);
            }
        }
        catch (Exception ex)
        {
            return default(ReturnType);
        }
    }

But I always get this error:

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

Upvotes: 2

Views: 674

Answers (3)

Jamiec
Jamiec

Reputation: 136074

The object you're trying to deserialize has a single property Result containing the array of ContactType - you dont have that in your object model. Try deserializing to this object:

public class MyClass // give this a more meaningful name
{
    public List<ContactType> Result{ get; set; }
}

public class ContactType
{
    public int Id { get; set; }
    public string Type { get; set; }
}

and then:

...
var test = await _items.GetContactTypes<MyObject>(AuthToken.access_token);
...

Upvotes: 3

adaam
adaam

Reputation: 3706

If you generate the C# classes for this JSON at json2csharp.com you will see that it creates two classes: ContactType and RootObject:

public class ContactType
{
    public int Id { get; set; }
    public string Type { get; set; }
}

public class RootObject
{
    public List<ContactType> Result { get; set; }
}

Your code is failing because it is trying to deserialize the JSON to type List<ContactType> when it is actually of type RootObject with a containing list.

So if you deserialize to type of RootObject first like so:

JsonConvert.DeserializeObject<RootObject>(str)

You can then access the list inside of the deserialized RootObject object.

Upvotes: 1

Maximilian Riegler
Maximilian Riegler

Reputation: 23506

You probably need a wrapper class for this, since the json object is not just an array itself but with a node "Result" with the value of that array.

public class ContactResult
{
    public List<ContactType> Result {get; set;}
}

And then call your method with that wrapper class:

var test = await _items.GetContactTypes<ContactResult>(AuthToken.access_token);

Upvotes: 1

Related Questions