繁体   English   中英

使用Json.Net进行条件数组/对象反序列化

[英]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;

还是我完全在错误的树上吠叫,这件事还有更优雅的解决方案?

你至少可以取代JObject.Parse()JToken.Parse()因为JToken是两个基类JObjectJArray 然后,您可以检查结果是JArray还是JObject (或者可能是JValue例如整数)。

var result = JToken.Parse(response);

if (result is JArray)
{
    // ...
}
else if (result is JObject)
{
    // ...
}

还可以查看JToken文档

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM