使用变量属性名称和嵌套列表将JSON反序列化为对象

时间:2018-01-09 06:58:04

标签: c# .net json.net

我有一堆API在响应正文中生成以下两种回复:

{ "error": null, "object_type": { /* some object */ } }
{ "error": null, "object_type": [{ /* some object */ }, { /* some object */ }, ...] }

虽然我有一个对应于对象结构的类,但我希望将API端点直接反序列化为类的对象或List<class>,而不创建一些“结果”类来匹配响应JSON结构。这可能吗?

例如,有2个API:

/api/getAllCompanies

返回

{ "error": null, "company": [ { "name": "Microsoft", "country": "US" }, { "name": "Apple", "country": "US" } ]

,而

/api/getUserCompany

返回

{ "error": null, "company": { "name": "Microsoft", "country": "US" } }

我在代码中有一个类:

public class Company {
    string Name { get; set; }
    string Country { get; set; }
}

如何在不创建其他类的情况下直接将数据反序列化为Company对象或List<Company>

(JSON属性名称(company)是已知的,因此不需要在别处提取它。)

我一直在尝试首先将响应JSON反序列化为ExpandoObject,然后使用the code here将属性复制到目标类的实例,然后使用以下代码将其转换,但这似乎不适用于列表。

private static async Task<T> GetApiObject<T>(string api, string extractedObjName) where T: class, new()
    {
        var retstr = await /* get API response as string */;
        dynamic retobj = JsonConvert.DeserializeObject<ExpandoObject>(retstr, new ExpandoObjectConverter());
        var ret = new T();
        Mapper<T>.Map((ExpandoObject)((IDictionary<string, object>)retobj)[extractedObjName], ret);
        return ret;
    }

1 个答案:

答案 0 :(得分:1)

您可以使用JObejct在将其反序列化为对象之前提取所需的信息。

var str = "{ \"error\": null, \"company\": [{ \"name\": \"Microsoft\", \"country\": \"US\" } ,{ \"name\": \"Apple\", \"country\": \"US\" } ]}";
var temp = JObject.Parse(str).GetValue("company");
var companies = temp.Select(x => x.ToObject<Company>()).ToList();

/api/getUserCompany

也是如此
var str = "{ \"error\": null, \"company\": { \"name\": \"Microsoft\", \"country\": \"US\" } }";
var temp = JObject.Parse(str).GetValue("company");
var company = temp.ToObject<Company>();