簡體   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