Maison >développement back-end >C++ >Comment puis-je gérer les tableaux et objets JSON ambigus pendant la désérialisation ?
Désérialisation JSON : gestion des tableaux et des objets ambigus
Lors du traitement des données JSON, vous rencontrez souvent des incohérences structurelles. Certaines propriétés peuvent être représentées sous forme de tableau dans une instance et sous forme d'objet dans une autre instance. Cela peut entraîner des problèmes lors de la désérialisation, en particulier lors de l'utilisation de classes de type sécurisé.
Question :
Considérez les données JSON suivantes renvoyées par Facebook :
Post mural (objet) :
<code class="language-json"> { "description": "", "permalink": "..." }</code>
Post photo (tableau) :
<code class="language-json"> { "media": [ { "href": "...", "src": "..." } ] }</code>
Post mural mobile (objet) :
<code class="language-json"> { "name": null, "caption": null, "media": {} }</code>
Dans le cas de publications murales mobiles, la propriété "media" est représentée comme un objet vide au lieu d'un tableau. Cette différence entraîne l'échec de la désérialisation lors de l'utilisation d'une classe qui attend un tableau d'objets « FacebookMedia ».
Solution : Convertisseur JSON personnalisé
Pour gérer cette situation, nous pouvons créer un convertisseur JSON personnalisé. Ce convertisseur examinera la structure JSON et renverra une liste ou null en fonction de la présence d'un tableau ou d'un objet.
<code class="language-csharp">public class FacebookMediaJsonConverter : JsonConverter { public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.TokenType == JsonToken.StartArray) return serializer.Deserialize<List<FacebookMedia>>(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<FacebookMedia>); } }</code>
Utilisation :
Pour utiliser un convertisseur, annotez les propriétés de votre classe avec l'attribut [JsonConverter]
:
<code class="language-csharp">[JsonConverter(typeof(FacebookMediaJsonConverter))] public List<FacebookMedia> Media { get; set; }</code>
La désérialisation gérera désormais avec succès les tableaux et les objets de la propriété "Media".
Extensions pour un seul objet :
Si vous souhaitez recevoir une liste même avec un seul objet, vous pouvez étendre le convertisseur pour convertir un seul objet en liste.
<code class="language-csharp">public class SingleValueArrayConverter<T> : 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<T> { instance }; } else if (reader.TokenType == JsonToken.StartArray) { result = serializer.Deserialize(reader, objectType); } else { throw new JsonSerializationException("Unexpected token type."); } return result; } // ... 转换器实现的其余部分 ... }</code>
En utilisant un convertisseur JSON personnalisé, nous pouvons gérer les incohérences dans la structure JSON et garantir une désérialisation réussie.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!