【问题标题】:How can I deserialize JSON to a custom type which has a property of type IEnumerable<dynamic>?如何将 JSON 反序列化为具有 IEnumerable<dynamic> 类型属性的自定义类型?
【发布时间】:2019-07-29 09:34:29
【问题描述】:

我正在编写一个控制台应用程序来从第 3 方 API 检索 JSON 数据。我无法控制 API 数据结构或功能。

我进行的几次调用将返回多个“页面”数据。数据是某种类型的对象的集合,例如用户。

我在我的应用中创建了类来匹配来自 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; }
}

对于这些调用,API 响应始终采用相同的格式。虽然“数据”数组中的实际对象类型会因调用的不同而有所不同。

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

我创建了一个类来尝试反序列化这些。 Data 属性的 dynamic[] 类型仅用于说明目的,如果有更好的方法,我很乐意更改它。

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

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

我想让数据集合解析为它包含的对象的适当类型。例如

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);

反序列化成功,但数据集合是 JObject 类型,无法转换为正确的类型(User、FooBar)。

如果可能,我会尽量避免为每个请求编写特定的响应对象类。

当我请求它时,我会知道我在集合中期望的对象类型,因此我可以将该类型传递给反序列化器,但我不清楚如何在这种特定情况下实现它。 像下面的伪代码这样的东西是理想的。

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

感谢您的帮助!

【问题讨论】:

  • 任何时候看到dynamic,你都需要问自己“有没有更好的方法”,99 次超过 100 次。它通过创建更多问题来解决 1 个问题

标签: c# json.net deserialization


【解决方案1】:

你可以像这样使用泛型类型 T:

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

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

【讨论】:

  • 感谢 Guilhem,这正是我缺少的步骤!
猜你喜欢
  • 1970-01-01
  • 2012-07-30
  • 2021-06-06
  • 2020-02-19
  • 2018-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多