JSON Deserialization: lidar com matrizes e objetos ambíguos
Ao processar dados JSON, você geralmente encontra inconsistência estrutural. Algumas propriedades podem ser representadas como matrizes em uma instância e como objetos em outro. Isso pode causar problemas durante a desserialização, especialmente ao usar classes seguras de tipo.
pergunta:
Considere os seguintes dados JSON retornados pelo Facebook:
Wall Posts (object):
] {
"description": "",
"permalink": "..."
}
Postagens fotográficas (Array):
{
"media": [
{
"href": "...",
"src": "..."
}
]
}
Mobile Wall Posts (object):
{
"name": null,
"caption": null,
"media": {}
}
No caso de mover as postagens da parede, o atributo "Media" é representado como um objeto vazio em vez de uma matriz. Essa diferença faz com que a desserialização falhe ao usar uma classe que espera uma matriz de objetos "FacebookMedia".
Solução: Converter JSON personalizado
Para lidar com essa situação, podemos criar um conversor JSON personalizado. Este conversor verificará a estrutura JSON e retornará uma lista ou nulo com base na presença de uma matriz ou 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 o conversor, use [JSONCONVERTER]
classe de comentário do atributo:
[JsonConverter(typeof(FacebookMediaJsonConverter))]
public List Media { get; set; }
Extensões para objetos únicos:
Se você deseja que uma lista seja recebida, mesmo que apenas um objeto, poderá estender o conversor para converter um único objeto em uma lista.
classe 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;
}
// ... 转换器实现的其余部分 ...
}
Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.
Copyright© 2022 湘ICP备2022001581号-3