[英]Conditional array/object deserialisation with Json.Net
我正在使用Json.Net库(用于.NET v3.5)来处理来自EBoss CRM API的响应的反序列化。 就我所见,API文档相当参差不齐,所以我不得不自己戳一下它,以查看可以引起什么样的响应。
我想拥有一个包装器类EBossApiResponse<T>
,该类将提供API发送回的任何错误消息的属性,以及一个包含类型T
的反序列化数据的属性(该属性将限制为抽象基类,用作我为对返回的数据进行建模而创建的任何类的基础类型)。
我最初的戳发现了第一个问题。 有效请求可以返回对象数组,例如: https : //ebosscrm.com/api.php/job_type.json
这将很容易反序列化为List<EBossJobType>
的假设T
请注意,结果中没有错误属性。
对同一端点的格式错误的请求会返回不同的内容: 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>
类型(如果为true,则填充错误消息,但保留.Data
属性== null),或者反序列化为正确的List<EBossEntityType>
,创建一个新的EBossApiResponse<List<EBossEntityType>>
,并设置其.Data
属性。
然后我意识到o.SelectToken("message")
将不起作用,因为o
将是一个数组,而不是一个对象。 .SelectToken()
可以采用"[0].message"
形式的模式来获取第一项的message属性?
这个怎么样?
JObject o = JObject.Parse(response);
JArray arr = o as JArray;
return (arr != null && (JObject)arr[0].SelectToken("message") != null)
|| o.SelectToken("error") != null;
还是我完全在错误的树上吠叫,这件事还有更优雅的解决方案?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.