Maison >développement back-end >C++ >Comment désérialiser JSON avec des touches numériques dynamiques à l'aide de Newtonsoft.Json ?

Comment désérialiser JSON avec des touches numériques dynamiques à l'aide de Newtonsoft.Json ?

DDD
DDDoriginal
2025-01-13 19:07:44695parcourir

How to Deserialize JSON with Dynamic Numeric Keys Using Newtonsoft.Json?

Comment désérialiser un sous-objet avec des noms de clés dynamiques (numériques) ?

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é.

Structure JSON

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.

Tentatives et défis initiaux

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.

Convertisseur JSON personnalisé

Pour résoudre ce problème, un convertisseur JSON personnalisé est requis. TypedExtensionDataConverterRé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.

Solution complète

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn