json Deserialization: manejar matrices y objetos ambiguos
Al procesar los datos de JSON, a menudo encuentra una inconsistencia estructural. Algunas propiedades pueden representarse como matrices en una instancia y como objetos en otro. Esto puede causar problemas durante la deserialización, especialmente cuando se usa clases de tipo seguro.
pregunta:
Considere los siguientes datos JSON devueltos por Facebook:
Wall Posts (Object):
] {
"description": "",
"permalink": "..."
}
Photo Publics (Array):
{
"media": [
{
"href": "...",
"src": "..."
}
]
}
móvil Publicaciones de pared (objeto):
{
"name": null,
"caption": null,
"media": {}
}
En el caso de mover las publicaciones de la pared, el atributo "Media" se representa como un objeto vacío en lugar de una matriz. Esta diferencia hace que la deserialización falle al usar una clase que espera una variedad de objetos "FacebookMedia".
Solución: Converter JSON Custom
Para manejar esta situación, podemos crear un convertidor JSON personalizado. Este convertidor verificará la estructura JSON y devolverá una lista o nula en función de la presencia de una matriz u objeto.
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);
}
}
uso:
para usar el convertidor, use [jsonConverter]
Atribute Comment Class:
[JsonConverter(typeof(FacebookMediaJsonConverter))]
public List Media { get; set; }
Extensions para objetos individuales:
Si desea que se reciba una lista, incluso si solo un objeto, puede extender el convertidor para convertir un solo objeto en una lista.
Clase pública SingleValueArrayConverter
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;
}
// ... 转换器实现的其余部分 ...
}
Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.
Copyright© 2022 湘ICP备2022001581号-3