JSON Deserialization: Handle ambiguous arrays and objects
When processing JSON data, you often encounter structural inconsistency. Some properties may be represented as arrays in one instance and as objects in another. This can cause problems during deserialization, especially when using type-safe classes.
question:
Consider the following JSON data returned by Facebook:
Wall posts (object):
] {
"description": "",
"permalink": "..."
}
Photo posts (array):
{
"media": [
{
"href": "...",
"src": "..."
}
]
}
Mobile wall posts (object):
{
"name": null,
"caption": null,
"media": {}
}
In the case of moving wall posts, the "media" attribute is represented as an empty object instead of an array. This difference causes deserialization to fail when using a class that expects an array of "FacebookMedia" objects.
Solution: Custom JSON Converter
To handle this situation, we can create a custom JSON converter. This converter will check the JSON structure and return a list or null based on the presence of an array or object.
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);
}
}
usage:
To use the converter, use [JsonConverter]
attribute comment class:
[JsonConverter(typeof(FacebookMediaJsonConverter))]
public List Media { get; set; }
Now, deserialization will successfully process the array and object of the "Media" attribute.
Extensions for single objects:
If you want a list to be received even if only one object, you can extend the converter to convert a single object to a list.
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;
}
// ... 转换器实现的其余部分 ...
}
By using a custom JSON converter, we can handle inconsistencies in JSON structures and ensure successful deserialization.
Disclaimer: All resources provided are partly from the Internet. If there is any infringement of your copyright or other rights and interests, please explain the detailed reasons and provide proof of copyright or rights and interests and then send it to the email: [email protected] We will handle it for you as soon as possible.
Copyright© 2022 湘ICP备2022001581号-3