使用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。请注意,结果中没有error属性。

但是,对同一个端点的格式错误的请求会返回不同的结果: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"形式的模式来获取第一个项目的消息属性?

这个怎么样?

JObject o = JObject.Parse(response);
JArray arr = o as JArray;
return (arr != null && (JObject)arr[0].SelectToken("message") != null)
|| o.SelectToken("error") != null;

还是我完全搞错了,而这整件事有一个更优雅的解决方案?

您至少可以用JToken.Parse()替换JObject.Parse(),因为JTokenJObjectJArray的基类。然后,您可以检查结果是JArray还是JObject(或者可能是像整数一样的JValue)。

var result = JToken.Parse(response);
if (result is JArray)
{
// ...
}
else if (result is JObject)
{
// ...
}

还可以查看JToken的文档。

相关内容

  • 没有找到相关文章

最新更新