我正在做一些web API集成与Newtonsoft。Json,和往常一样,我必须做一些愚蠢的特技来正确地反序列化他们发回的内容。
在这种情况下,API将发送类似于这种结构的响应:{ "contacts": [ ... ], "has-more": true, "offset": 38817 }
"has-more"one_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。好了,都准备好了,这是你的对象。"
我怀疑这涉及到自定义JsonConverter
或IContractResolver
的一些技巧,但我只是没有在这里连接点。我尝试做一个简单的自定义契约解析器,但它似乎使用契约解析器将对象属性名称解析为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