IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Désérialiser un json contenant un array vers des attributs d'une classe structurée


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut Désérialiser un json contenant un array vers des attributs d'une classe structurée
    Bonjour,

    Je reçois un JSON qui a cette (sale) tête :
    Code json : Sélectionner tout - Visualiser dans une fenêtre à part
    {"authenticated":true,"serverinfo":["1.0",[["1002","French"],["1001","English"]]]}

    Je souhaite le désérialiser dans une classe qui a cette tête :!
    Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    public class AuthenticationType
    {
       [JsonPropertyName("authenticated")]
       public bool Authenticated {get;set;}
     
       [JsonPropertyName("serverinfo")]
       public ServerInfoType ServerInfo {get;set;}
    }
     
    public class ServerInfoType 
    {
       public string Version {get;set;}
       public List<LanguageType> Languages {get;set;}
    }
     
    public class LanguageType
    {
       public string Code{get;set;}
       public string Name {get;set;}
    }

    On voir que pour le "serverinfo" dans le JSON, Version et Languages[] ne sont pas déclarés en tant que tel, ce sont simplement des lignes d'un object[]
    Idem pour "language", on n'a qu'un string[] sans les noms d'attributs.

    Est-ce qu'il existe un moyen, si possible avec System.Text.Json de mettre des décorateurs du type :
    Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    public class ServerInfoType 
    {
       [JsonArrayIndex(0)]
       public string Version {get;set;}
     
       [JsonArrayIndex(1)]
       public List<LanguageType> Languages {get;set;}
    }
     
    public class LanguageType
    {
       [JsonArrayIndex(0)]
       public string Code{get;set;}
     
       [JsonArrayIndex(1)]
       public string Name {get;set;}
    }

    Je trouve qu'on peut créer un JsonConverter mais déjà j'arrive pas à le faire marcher, mais surtout, visiblement il en faudra un par type. J'ai plus d'une trentaine de types de la sorte à gérer, j'aimerais éviter de m'amuser à écrire plus de code pour la désarialisation que pour l'ensemble du reste du programme...

  2. #2
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    2 966
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 2 966
    Par défaut
    En confiant ton JSON à https://jsonformatter.org/json-to-csharp.
    J'obtiens ce code C#.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    // <auto-generated />
    //
    // To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
    //
    //    using CodeBeautify;
    //
    //    var welcome4 = Welcome4.FromJson(jsonString);
     
    namespace CodeBeautify
    {
        using System;
        using System.Collections.Generic;
     
        using System.Globalization;
        using Newtonsoft.Json;
        using Newtonsoft.Json.Converters;
     
        public partial class Welcome4
        {
            [JsonProperty("authenticated")]
            public bool Authenticated { get; set; }
     
            [JsonProperty("serverinfo")]
            public Serverinfo[] Serverinfo { get; set; }
        }
     
        public partial struct Serverinfo
        {
            public string String;
            public string[][] StringArrayArray;
     
            public static implicit operator Serverinfo(string String) => new Serverinfo { String = String };
            public static implicit operator Serverinfo(string[][] StringArrayArray) => new Serverinfo { StringArrayArray = StringArrayArray };
        }
     
        public partial class Welcome4
        {
            public static Welcome4 FromJson(string json) => JsonConvert.DeserializeObject<Welcome4>(json, CodeBeautify.Converter.Settings);
        }
     
        public static class Serialize
        {
            public static string ToJson(this Welcome4 self) => JsonConvert.SerializeObject(self, CodeBeautify.Converter.Settings);
        }
     
        internal static class Converter
        {
            public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
            {
                MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
                DateParseHandling = DateParseHandling.None,
                Converters =
                {
                    ServerinfoConverter.Singleton,
                    new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
                },
            };
        }
     
        internal class ServerinfoConverter : JsonConverter
        {
            public override bool CanConvert(Type t) => t == typeof(Serverinfo) || t == typeof(Serverinfo?);
     
            public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
            {
                switch (reader.TokenType)
                {
                    case JsonToken.String:
                    case JsonToken.Date:
                        var stringValue = serializer.Deserialize<string>(reader);
                        return new Serverinfo { String = stringValue };
                    case JsonToken.StartArray:
                        var arrayValue = serializer.Deserialize<string[][]>(reader);
                        return new Serverinfo { StringArrayArray = arrayValue };
                }
                throw new Exception("Cannot unmarshal type Serverinfo");
            }
     
            public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
            {
                var value = (Serverinfo)untypedValue;
                if (value.String != null)
                {
                    serializer.Serialize(writer, value.String);
                    return;
                }
                if (value.StringArrayArray != null)
                {
                    serializer.Serialize(writer, value.StringArrayArray);
                    return;
                }
                throw new Exception("Cannot marshal type Serverinfo");
            }
     
            public static readonly ServerinfoConverter Singleton = new ServerinfoConverter();
        }
    }

Discussions similaires

  1. affichage des attributs d'une classe
    Par dolsky dans le forum VB.NET
    Réponses: 9
    Dernier message: 02/06/2009, 15h13
  2. Réponses: 12
    Dernier message: 20/05/2009, 15h32
  3. Réponses: 12
    Dernier message: 30/06/2006, 16h46
  4. récupérer le nom des attributs d'une classe
    Par danyboy85 dans le forum API standards et tierces
    Réponses: 2
    Dernier message: 22/06/2006, 11h42
  5. Réponses: 2
    Dernier message: 27/03/2005, 16h09

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo