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