简体   繁体   中英

How can I deserialize JSON to a custom type which has a property of type IEnumerable<dynamic>?

I'm writing a console app to retrieve JSON data from a 3rd party API. I have no control over the API data structures or functionality.

Several of the calls I make will return multiple 'pages' of data. The data is a collection of objects of a certain type eg User.

I have created classes in my app to match the various data types from the API.

public class User
{
    [JsonProperty("id")]
    public int ID { get; set; }

    [JsonProperty("first_name")]
    public string FirstName { get; set; }

    [JsonProperty("last_name")]
    public string LastName { get; set; }
}

public class FooBar
{
    [JsonProperty("foo")]
    public string Foo { get; set; }

    [JsonProperty("bar")]
    public string Bar { get; set; }
}

The API response is always in the same format for these calls. While the actual object types in the "data" array will differ depending on what call has been made.

{
 "paging":{"page":1},  
 "data":[{<object>}, {<object>}, {<object>},...]
}

I have created a class to try to deserialize these. The dynamic[] type for the Data property is for illustrative purposes and I am happy to change it if there is a better approach.

public class ApiResponseObject
{
    [JsonProperty("paging")]
    public Paging PagingInfo { get; set; }

    [JsonProperty("data")]
    public dynamic[] Data { get; set; }
}

And I would like to have the Data collection resolve to the appropriate type for the objects it contains. eg

string userJson = "{\"paging\":{\"page\":1},\"data\":[{\"id\":1,\"first_name\":\"Joe\",\"last_name\":\"Bloggs\"},{\"id\":2,\"first_name\":\"Jane\",\"last_name\":\"Doe\"}]}"; // json string would come from API
string foobarJson = "{\"paging\":{\"page\":1},\"data\":[{\"foo\":\"Lorem\",\"bar\":\"Ipsum\"},{\"foo\":\"Dolor\",\"bar\":\"Amet\"}]}";

var userResponse = JsonConvert.DeserializeObject<ApiResponseObject>(userJson);
var foobarResponse = JsonConvert.DeserializeObject<ApiResponseObject>(foobarJson);

The deserialization succeeds but the Data collection is of type JObject and cannot be cast into the correct type (User, FooBar).

I am trying to avoid having to write specific response object classes for each request if possible.

I will know what type of object I am expecting in the collection when I am requesting it so I could pass that type to the deserializer but I'm not clear on how to achieve that in this particular scenario. Something like the below psuedo code would be ideal.

var userResponse = JsonConvert.DeserializeObject<ApiResponseObject<User>>(userJson);

Thanks for your help!

You can use the generic type T, like this :

public class ApiResponseObject<T>
{
    [JsonProperty("paging")]
    public Paging PagingInfo { get; set; }

    [JsonProperty("data")]
    public T[] Data { get; set; }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM