JsonConvert.DeserializeAnonymousType绕过数组

问题描述

我写了一个包装程序来处理我的应用程序如何与使用通用反序列化到的第三方API交互的情况:

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 { ... }
}

我最初使用的版本返回的是“扁平”对象,如下所示:

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

该版本最近已被弃用,新版本现在返回包装在数据数组中的所有响应,即使对于像这样的单个响应:

data: [{
    "_id": 44322889,}]

是否可以更新上述反序列化代码,因此不必更新所有利用此代码的类?

解决方法

我遇到了一些问题,其中数据模型像您的示例一样被包装在一个附加对象中。一种对我有用的解决方案,只需很少的更改即可将TModel类包装在字典中。

因此,您在此处的行将变为:

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

这有点优雅,但是如果您不想添加其他模型类,通常这是最好的解决方案。

,

我最终意识到,现在我得到了dictionary<string,List>,我可以使用GetValueOrDefault('data')从该键中显式获得所需的值:

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