Lorsque vous traitez des structures JSON complexes contenant des sous-objets avec des noms de clés dynamiques, les désérialiser à l'aide de Newtonsoft JSON.NET peut présenter des défis. Cet article examinera des scénarios impliquant de telles structures et fournira une solution complète utilisant un convertisseur JSON personnalisé.
Considérez la structure JSON suivante :
<code class="language-json">{ "users" : { "parentname":"test", "100034" : { "name" : "tom", "state" : "WA", "id" : "cedf-c56f-18a4-4b1" }, "10045" : { "name" : "steve", "state" : "NY", "id" : "ebb2-92bf-3062-7774" }, "12345" : { "name" : "mike", "state" : "MA", "id" : "fb60-b34f-6dc8-aaf7" } } }</code>
Dans cette structure, l'objet "users" contient un mélange de propriétés connues ("parentname") et de propriétés inconnues (avec des touches numériques représentant les objets enfants). L'objectif est de désérialiser cette structure en un modèle objet C#, où les sous-objets sont représentés sous forme de classes fortement typées.
Une première tentative de désérialisation de JSON à l'aide du code JSON.NET standard pourrait ressembler à ceci :
<code class="language-csharp">class RootObject { public string ParentName { get; set; } public Dictionary<string, User> users { get; set; } } class User { public string name { get; set; } public string state { get; set; } public string id { get; set; } }</code>
La désérialisation vers ce modèle objet échoue en raison de propriétés inconnues dans l'objet "utilisateurs". JSON.NET s'attend par défaut à ce que les noms de propriété correspondent aux propriétés de classe et, comme la clé numérique ne correspond à aucune propriété de la classe User, le processus de désérialisation échoue.
Pour résoudre ce problème, un convertisseur JSON personnalisé est requis. TypedExtensionDataConverter
Résout ce problème avec élégance. Voici le code :
<code class="language-csharp">public class TypedExtensionDataConverter<T> : JsonConverter { // ... [此处省略实现,篇幅原因] }</code>
Ce convertisseur permet de désérialiser des propriétés inconnues dans un conteneur typé, en l'occurrence un dictionnaire d'objets Utilisateur :
<code class="language-csharp">[JsonConverter(typeof(TypedExtensionDataConverter<Users>))] class Users { public Users() { this.UserTable = new Dictionary<string, User>(); } [JsonProperty("parentname")] public string ParentName { get; set; } [JsonTypedExtensionData] public Dictionary<string, User> UserTable { get; set; } }</code>
En utilisant JsonTypedExtensionDataAttribute
, le convertisseur sait sérialiser/désérialiser les propriétés inconnues dans le dictionnaire UserTable
.
Avec un convertisseur personnalisé, la solution complète ressemble à ceci :
<code class="language-csharp">class RootObject { [JsonProperty("users")] public Users Users { get; set; } } [JsonConverter(typeof(TypedExtensionDataConverter<Users>))] class Users { // ... [如上实现] } class User { // ... [不变] }</code>
La structure JSON désérialisée remplira désormais RootObject
avec les valeurs attendues, y compris les sous-objets stockés dans le dictionnaire Users
au sein de l'objet UserTable
.
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!