将第一个不匹配任何目标对象属性的属性反序列化为特定属性

本文关键字:属性 反序列化 不匹配 任何 目标对象 第一个 | 更新日期: 2023-09-27 18:09:37

我正在做一些web API集成与Newtonsoft。Json,和往常一样,我必须做一些愚蠢的特技来正确地反序列化他们发回的内容。

在这种情况下,API将发送类似于这种结构的响应:
{ "contacts": [ ... ], "has-more": true, "offset": 38817 }

"has-more"answers"offset"属性在不同的方法响应上几乎是恒定的,并且在我要反序列化到的响应对象上已经相应地定义了。响应对象看起来像这样:

public class APIResponse {
    public JContainer Result { get; set; }
    [JsonProperty("has-more")]
    public bool HasMore { get; set; }
    [JsonProperty("offset")]
    public int Offset { get; set; }
}

第一个"contacts"属性是可以改变的;对于某些方法,我可能会得到"联系人",有些可能会得到"公司",还有一些可能会得到"谁知道什么"。我也没有办法确定每个响应都会有这样一个"变量"属性,也不确定它会是第一个,从位置上讲。

对于这个例子,我想要发生的是反序列化器查看Json并说,"让我们看看,我没有看到任何映射到'contacts',所以我们将把它放入'Result',然后我可以从JsonProperty属性中看到'has-more'和'offset'进入HasMore和offset。好了,都准备好了,这是你的对象。"

我怀疑这涉及到自定义JsonConverterIContractResolver的一些技巧,但我只是没有在这里连接点。我尝试做一个简单的自定义契约解析器,但它似乎使用契约解析器将对象属性名称解析为JSON文本中查找的属性名称,反之亦然。

将第一个不匹配任何目标对象属性的属性反序列化为特定属性

您可以为每个响应类型使用基类+派生。

public class APIResponseBase {
    [JsonProperty("has-more")]
    public bool HasMore { get; set; }
    [JsonProperty("offset")]
    public int Offset { get; set; }
}
public class ContactsResponse : APIResponseBase {
  public IEnumerable<Contact> Contacts { get; set; }
}
public class CompaniesResponse : APIResponseBase {
  public IEnumerable<Company> Companies { get; set; }
}
var contactsResponse = JsonConvert.Deserialize<ContactsResponse>(json);
IEnumerable<Contact> contacts = contactsResponse.Contacts