我使用Json.Net库(用于.NET v3.5)来处理来自EBoss CRM API的反应的反序列化。据我所见,API文档相当多,所以我不得不自己捅一下,看看可以引发什么样的反应。有条件的数组/对象反序列化与Json.Net
我想拥有一个包装类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;
}
我可以用这个方法来然后要么直接deserialise向右侧EBossApiResponse<T>
类型(如果是真的,填充错误消息,但离开.Data
财产== NULL),或deserialise右边的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;
还是我完全找错了树,还有一个更优雅的解决这件事?
我想知道在地球上我怎么可能错过了阅读文档,并刚回到他们我意识到为什么:我正在使用.NET Framework v3.5进行项目集成,因此Json.Net 3.5,JToken.Parse()稍后被引入Json.Net。我没有它:( –
回来进行清理。虽然它当时没有解决问题,但现在肯定是正确的答案。 –