Zze
Zze

Reputation: 18835

JsonConvert.DeserializeAnonymousType Bypass Array

I wrote a wrapper to handle how my app interacts with a 3rd party API that uses a generic to de-serialize onto:

protected static async Task<TResult> Get<TResult, TApiModel>(string url, Dictionary<string, string> additionalHeaders = null)
        where TResult : IBaseModel, new()
        where TApiModel : IBaseApiResult<TResult>, new()
{
    var response = await HttpClient.SendAsync(requestMessage).ConfigureAwait(false);
    ...
    var data = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

    try
    {
        var deserializedObject = JsonConvert.DeserializeAnonymousType(data, new TApiModel());
        var model = deserializedObject.ConvertToBaseModel();
        return model;
    }
    catch { ... }
}

The version I was using was originally using was returning a "flat" objects as a result like this:

{
    "_id": 44322889,
    "bio": "...",
    "created_at": "2013-06-03T19:12:02Z",
    "display_name": "...",
}

That version was recently deprecated and the new version now returns all responses wrapped in a data array even for singular responses like this:

data: [{
    "_id": 44322889,
    "bio": "...",
    "created_at": "2013-06-03T19:12:02Z",
    "display_name": "...",
}]

Is there a way to update my the above deserialize code so I don't have to update all of the classes which utilize this?

Upvotes: 0

Views: 147

Answers (2)

Zze
Zze

Reputation: 18835

I ended up realizing that now I am getting a dictionary<string, List>, I can use GetValueOrDefault('data') to explicitly get the value I need from that key:

var model = JsonConvert.DeserializeObject<Dictionary<string, List<TApiModel>>>(data).GetValueOrDefault("data").FirstOrDefault().ConvertToBaseModel();

Upvotes: 0

ekke
ekke

Reputation: 1410

I have had issues in which the data model gets wrapped in an addition object like in your example. One solution which worked for me with fairly minimal changes was the wrap the TModel class in a dictionary.

So your line here would become:

var deserializedObjectDictionary = JsonConvert.DeserializeAnonymousType(data, new Dictionary<string, List<TApiModel>>());
// now unwrap dictionary to extract object

It's a little inelegant but often it's the best solution if you don't want to add additional model classes.

Upvotes: 2

Related Questions