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 :

deserialization chaine XML


Sujet :

C#

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Février 2016
    Messages : 22
    Points : 20
    Points
    20
    Par défaut deserialization chaine XML
    Bonjour a tous!

    Je développe un projet console en C#. Dans ce projet je reçois une chaîne XML d'un service REST qui récupère et insère des données dans une base de données. Les communication se font en XML. Le service REST gère le XML avec SimpleXML:
    Je demande au service de m'envoyer une liste de datas que je deserialize en un objet de classe Datas. Quand je lance le projet, il y a une exception qui me dit qu'il y a une erreur dans la chaîne.
    J'ai chercher un peu et j'ai trouvé.

    Voici les classes:
    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
    [XmlRoot(ElementName = "Data")]
        public class Data
        {
            [XmlElement(ElementName = "Time")]
            public double Time { get; set; }
            [XmlElement(ElementName = "Z1Pow")]
            public double Z1Pow { get; set; }
            [XmlElement(ElementName = "Z1Valid")]
            public string Z1Valid { get; set; }
            [XmlElement(ElementName = "Z1Temp")]
            public string Z1Temp { get; set; }
            [XmlElement(ElementName = "Z2Pow")]
            public string Z2Pow { get; set; }
            [XmlElement(ElementName = "Z2Valid")]
            public string Z2Valid { get; set; }
            [XmlElement(ElementName = "Z2Temp")]
            public string Z2Temp { get; set; }
            [XmlElement(ElementName = "Z3Pow")]
            public string Z3Pow { get; set; }
            [XmlElement(ElementName = "Z3Valid")]
            public string Z3Valid { get; set; }
            [XmlElement(ElementName = "Z3Temp")]
            public string Z3Temp { get; set; }
        }
     
        [XmlRoot(ElementName = "Datas")]
        public class Datas
        {
            [XmlElement(ElementName = "Data")]
            public List<Data> Data { get; set; }
        }
    *Classes générer avec http://xmltocsharp.azurewebsites.net/ donc pas d'erreur. J'ai juste passer Z1Pow de string a double

    Voila un exemple de chaine XML recu:
    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
    <Datas>
    	<Data>
    		<Time>1</Time>
    		<Z1Pow/>
    		<Z1Valid/>
    		<Z1Temp>350</Z1Temp>
    		<Z2Pow/>
    		<Z2Valid/>
    		<Z2Temp/>
    		<Z3Pow/>
    		<Z3Valid/>
    		<Z3Temp>150</Z3Temp>
    	</Data>
    	<Data>
    		<Time>1.1</Time>
    		<Z1Pow/>
    		<Z1Valid/>
    		<Z1Temp>343</Z1Temp>
    		<Z2Pow/>
    		<Z2Valid/>
    		<Z2Temp/>
    		<Z3Pow/>
    		<Z3Valid/>
    		<Z3Temp>175</Z3Temp>
    	</Data>
    </Datas>
    Le problème qui se pose est au niveau de la balise <Z1Pow/>.
    Comme dans la classe Z1Pow est un double il veut forcément une valeur dans cette balise. Si Z1Pow est un string aucun problème.
    Par exemple si il y a <Z1Pow>12.1656986</Z1Pow> ca passe (j'ai fait le test).
    Comment faire pour que lorsque Z1Pow n'a pas de valeur dans la chaine XML, l'objet est une propriété qui vaut 0.00?? L'avantage de mettre l'attribut en double plutôt qu'en string est que ca m'évite d'avoir à faire 30 000 double.Parse() dans mon code.

    Pour la deserialization j'utilise un un TextReader:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    using (TextReader reader = new StringReader(chaineXML))
                    { this.currentDatas = serializer.Deserialize(reader) as Datas; }
    *chaineXML=chaine recu du service REST. this.currentDatas est de classe Datas.

    Merci d'avance pour votre aide

  2. #2
    Expert confirmé

    Homme Profil pro
    Responsable déploiement (SCCM, InTune, GPO)
    Inscrit en
    Juillet 2014
    Messages
    3 184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Responsable déploiement (SCCM, InTune, GPO)
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2014
    Messages : 3 184
    Points : 5 755
    Points
    5 755
    Par défaut
    Si Z1Pow peut être null as tu envisagé d'utilisé un type double nullable ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    double? Z1Pow = 5.5;
    Z1Pow = null;
    Tu peut très bien remettre en forme après, avec la valeur par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if (Z1Pow == null)
          Z1Pow = default(double?);
    Mais si ç’a a été sérialiser en tant que string je trouve cela contre nature de vouloir changer le type dans le XML, si tu le change tu doit t'assurer que les valeurs soient cohérentes.

    Je serais toi je laisserai tel quelle, je désérialize comme sa a été sérialize en string.
    On peut ajouter une méthode GetZ1Pow à ta class 'Data' qui te retournera la valeur au format souhaité.

    Ça te donne une list/collection/tableau d'objet 'Data' au final ?

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Février 2016
    Messages : 22
    Points : 20
    Points
    20
    Par défaut
    Merci pour ta réponse.
    J'ai essayé en mettant double? à la place de double dans la classe Data, y a une erreur quand même.
    Pas grave, je vais remettre des string, pas trop le temps de bloquer la dessus =/ .
    Merci quand même^^!

    Oui en gros j'ai un objet de classe Datas qui contient une List<Data>

  4. #4
    Expert confirmé

    Homme Profil pro
    Responsable déploiement (SCCM, InTune, GPO)
    Inscrit en
    Juillet 2014
    Messages
    3 184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Responsable déploiement (SCCM, InTune, GPO)
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2014
    Messages : 3 184
    Points : 5 755
    Points
    5 755
    Par défaut
    Dans ta classe tu peut essayer de définir une valeur par défaut.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    public class Person
    {
        [DefaultValue(-1)]
        public int Age { get; set; }
     
        [XmlIgnore]
        public bool AgeSpecified { get { return Age >= 0; } }
    }
    Serialize nullable type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    [Serializable]
    public class MyClass
    {
        [XmlElement(IsNullable = true)]
        public int? Age { get; set; }
     
        public int MyClassB { get; set; }
    }

  5. #5
    Membre éprouvé
    Homme Profil pro
    Architecte technique
    Inscrit en
    Septembre 2005
    Messages
    462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 462
    Points : 1 056
    Points
    1 056
    Par défaut
    Salut,

    Tu peux utiliser "DefaultValueAttribute" :

    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
        [XmlRoot(ElementName = "Data")]
        public class Data
        {
            [XmlElement(ElementName = "Time")]
            public double Time { get; set; }
            [XmlElement(ElementName = "Z1Pow"), DefaultValue(0)]
            public double Z1Pow { get; set; }
            [XmlElement(ElementName = "Z1Valid")]
            public string Z1Valid { get; set; }
            [XmlElement(ElementName = "Z1Temp")]
            public string Z1Temp { get; set; }
            [XmlElement(ElementName = "Z2Pow")]
            public string Z2Pow { get; set; }
            [XmlElement(ElementName = "Z2Valid")]
            public string Z2Valid { get; set; }
            [XmlElement(ElementName = "Z2Temp")]
            public string Z2Temp { get; set; }
            [XmlElement(ElementName = "Z3Pow")]
            public string Z3Pow { get; set; }
            [XmlElement(ElementName = "Z3Valid")]
            public string Z3Valid { get; set; }
            [XmlElement(ElementName = "Z3Temp")]
            public string Z3Temp { get; set; }
        }
     
        [XmlRoot(ElementName = "Datas")]
        public class Datas
        {
            [XmlElement(ElementName = "Data")]
            public List<Data> Data { get; set; }
        }
    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
    static void Main(string[] args)
            {
                var value = @"<Datas>
    	<Data>
    		<Time>1</Time>
    		<Z1Pow/>
    		<Z1Valid/>
    		<Z1Temp>350</Z1Temp>
    		<Z2Pow/>
    		<Z2Valid/>
    		<Z2Temp/>
    		<Z3Pow/>
    		<Z3Valid/>
    		<Z3Temp>150</Z3Temp>
    	</Data>
    	<Data>
    		<Time>1.1</Time>
    		<Z1Pow/>
    		<Z1Valid/>
    		<Z1Temp>343</Z1Temp>
    		<Z2Pow/>
    		<Z2Valid/>
    		<Z2Temp/>
    		<Z3Pow/>
    		<Z3Valid/>
    		<Z3Temp>175</Z3Temp>
    	</Data>
    </Datas>";
     
                Datas result;
                var serializer = new XmlSerializer(typeof(Datas));
                using (TextReader textReader = new StringReader(value))
                {
                    result = serializer.Deserialize(textReader) as Datas;
                }
                Console.ReadLine();
            }
    J'ai essayé de mettre "0.00" mais valeur pas défaut mais pour le compilateur c'est 0.

    Edit : Grillé par ericlm128...

Discussions similaires

  1. envoyer une chaine XML contenant un paquet de BYTE
    Par mnemonic78 dans le forum C#
    Réponses: 1
    Dernier message: 17/06/2008, 08h51
  2. [XML 1.1] Règle de comparaison des noms et chaînes XML
    Par Hibou57 dans le forum XML/XSL et SOAP
    Réponses: 0
    Dernier message: 03/08/2007, 18h43
  3. Réponses: 4
    Dernier message: 11/05/2006, 14h41
  4. [VB.NET] Charger une chaine XML
    Par Dnx dans le forum ASP.NET
    Réponses: 11
    Dernier message: 17/03/2005, 14h55
  5. [VB.NET] Alimenter un dataset avec une chaine XML...
    Par David.V dans le forum ASP.NET
    Réponses: 3
    Dernier message: 25/05/2004, 09h09

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