我正在使用 Json.Net 库(用于 .NET v3.5)来处理来自 EBoss CRM API 的响应的反序列化。据我所见,API 文档相当参差不齐,因此我不得不亲自查看它以查看可以引发什么样的响应。
我想要一个包装类EBossApiResponse<T>
,它可以为 API 发回的任何错误消息提供属性,以及一个包含反序列化类型数据的属性T
(这将被限制为充当任何类的基础类型的抽象基类我创建以对返回的数据进行建模)。
我最初的戳揭示了第一个问题。一个有效的请求可以返回一个对象数组,例如:https ://ebosscrm.com/api.php/job_type.json
这将很容易反序列化为假设T
的List<EBossJobType>
. 请注意,结果中没有错误属性。
然而,对同一端点的格式错误的请求会返回不同的内容:https ://ebosscrm.com/api.php/job_type.json?search[foo]=1
在这种情况下,将返回一个数组,其中包含一个具有名为 的单个属性的对象message
。
(注意,有些调用的参数命名search[something]
是有效的,但foo
永远不是有效的something
)
也有可能返回显式错误。在我看来,API 正在捕获异常并格式化包含调试信息的 JSON 响应:https ://ebosscrm.com/api.php/candidates.json?uid=114&api_key=f34js3kj
在这种情况下,返回的 JSON 不是数组,而是单个对象。我不确定如何满足这些不同的响应结构。我最初的想法是有类似的东西:
protected bool IsNonDataResponse(string response)
{
JObject o = JObject.Parse(response);
return o.SelectToken("message") != null || o.SelectToken("error") != null;
}
然后我可以使用此方法直接反序列化为正确的EBossApiResponse<T>
类型(如果为真,填充错误消息但保留.Data
属性 == null),或者反序列化到右侧List<EBossEntityType>
,创建一个新EBossApiResponse<List<EBossEntityType>>
的并设置其.Data
属性。
然后我意识到这o.SelectToken("message")
行不通,因为o
它将是一个数组,而不是一个对象。是否可以.SelectToken()
通过表单的模式"[0].message"
来获取第一项的消息属性?
这个怎么样?
JObject o = JObject.Parse(response);
JArray arr = o as JArray;
return (arr != null && (JObject)arr[0].SelectToken("message") != null)
|| o.SelectToken("error") != null;
或者我是不是完全找错了树,而这整件事有一个更优雅的解决方案?