JSON 反序列化:處理不明確的數組和對象
在處理 JSON 數據時,經常會遇到結構不一致的情況。某些屬性在一個實例中可能表示為數組,而在另一個實例中則表示為對象。這在反序列化過程中可能會導致問題,尤其是在使用類型安全類時。
問題:
考慮 Facebook 返回的以下 JSON 數據:
牆面帖子(對象):
{
"description": "",
"permalink": "..."
}
照片帖子(數組):
{
"media": [
{
"href": "...",
"src": "..."
}
]
}
移動牆面帖子(對象):
{
"name": null,
"caption": null,
"media": {}
}
在移動牆面帖子的情況下,“media”屬性表示為空對象而不是數組。當使用期望“FacebookMedia”對像數組的類時,這種差異會導致反序列化失敗。
解決方案:自定義 JSON 轉換器
為了處理這種情況,我們可以創建一個自定義 JSON 轉換器。此轉換器將檢查 JSON 結構,並根據數組或對象的存在返回列表或 null。
public class FacebookMediaJsonConverter : JsonConverter
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.StartArray)
return serializer.Deserialize>(reader);
else
return null;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof(List);
}
}
用法:
要使用轉換器,請使用 [JsonConverter]
屬性註釋類中的屬性:
[JsonConverter(typeof(FacebookMediaJsonConverter))]
public List Media { get; set; }
現在,反序列化將成功處理“Media”屬性的數組和對象。
針對單個對象的擴展:
如果您希望即使只有一個對像也能收到列表,則可以擴展轉換器以將單個對象轉換為列表。
public class SingleValueArrayConverter : JsonConverter
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
object result;
if (reader.TokenType == JsonToken.StartObject)
{
T instance = (T)serializer.Deserialize(reader, typeof(T));
result = new List { instance };
}
else if (reader.TokenType == JsonToken.StartArray)
{
result = serializer.Deserialize(reader, objectType);
}
else
{
throw new JsonSerializationException("Unexpected token type.");
}
return result;
}
// ... 转换器实现的其余部分 ...
}
通過使用自定義 JSON 轉換器,我們可以處理 JSON 結構中的不一致性,並確保成功反序列化。
免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。
Copyright© 2022 湘ICP备2022001581号-3