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 :

XmlSerializer : sérialiser mon propre objet


Sujet :

C#

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    95
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 95
    Points : 62
    Points
    62
    Par défaut XmlSerializer : sérialiser mon propre objet
    Bonjour à tous,

    Je ne suis pas un expert en programmation C#, et je me trouve confronté à un problème assez gênant. J'ai un objet que je souhaiterai pouvoir sauvegarder et charger sur le disque, via un fichier TXT ou XML.

    En cherchant un peu sur le net, j'ai trouvé un exemple avec l'utilisation de XmlSerializer. Cependant, lorsque je crée une instance de cette classe, j'ai le message suivant qui s'affiche :

    XmlSerializer ser = new XmlSerializer(typeof(vqDatabase) /*this.GetType()*/);


    An unhandled exception of type 'System.InvalidOperationException' occurred in System.Xml.dll

    Additional information: VisoonQualitéWA.vqDatabase is inaccessible due to its protection level. Only public types can be processed.
    Pourtant tous les attributs de mon objet vqDatabase sont publics !!!

    Je ne comprends vraiment pas.

    A noter que vqDatabase, n'est ni plus ni moins qu'une liste de vqDocument. Faut-il définir les fonctions save et load pour vqDocument également ? Les attributs de vqDocument sont également publics.

    Merci à tous de l'aide que vous pouvez m'apporter.
    Bonne journée

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    311
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2003
    Messages : 311
    Points : 337
    Points
    337
    Par défaut
    Il faut que ta classe soit publique, et que tu aies un constructeur par défaut public

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    95
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 95
    Points : 62
    Points
    62
    Par défaut
    Citation Envoyé par zoubidaman Voir le message
    Il faut que ta classe soit publique, et que tu aies un constructeur par défaut public
    Merci, ça fonctionne, mais maintenant, j'ai un problème lorsque j'appelle la fonction Serialize

    Additional information: There was an error generating the XML document.
    Voici mon code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    String path = @"C:\database.xml";
     
                using (TextWriter writer = new StreamWriter(path, false))
                {
                    XmlSerializer ser = new XmlSerializer(typeof(vqDatabase) /*this.GetType()*/);
                    ser.Serialize(writer, this);
                    writer.Close();
                }
    Que faut-il rajouter dans mes objets pour que cela fonctionne correctement ?

    Merci d'avance

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par Pg043 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Additional information: There was an error generating the XML document.
    Regarde la InnerException pour avoir plus de détails sur l'erreur, sans ça on ne peut pas savoir ce qui ne va pas...

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    95
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 95
    Points : 62
    Points
    62
    Par défaut
    Citation Envoyé par tomlev Voir le message
    Regarde la InnerException pour avoir plus de détails sur l'erreur, sans ça on ne peut pas savoir ce qui ne va pas...
    J'ai essayé de résoudre quelques problèmes, mais ça ne passe toujours pas. Je repose mon problème :

    J'ai une classe Class1 qui contient une liste de Class2 comme le montre la déclaration :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    [XmlInclude(typeof(Class1))] 
    public class Class1
    {
        public List<Class2> db;
     
        public Class1()
        {
            db = new List<Class2>();
        }
    Or Class2 est une classe abstraite définie comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    [XmlInclude(typeof(Class2))] 
    public abstract class Class2
    {
        private String _attrib1;
        private Int32 _attrib2;
        ...
    }
    Et donc, j'ai ensuite plusieurs objets Class3 qui hérite de Class2 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    [XmlInclude(typeof(Class3))] 
    public class Class3 : Class2
    {
        private DateTime _attrib;
        ...
    }
    -----------------------------

    Ensuite, je déclare un objet Class1 qui va contenir plusieurs objets Class3

    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
    Class1 db = new Class1();
     
    // Création d'une nouvelle fiche de dysfonctionnement
    Class3 dys1 = new Class3();
    Class3 dys2 = new Class3();
     
    db.Add(dys1);
    db.Add(dys2);
     
    String path = @"C:\database.xml";
     
    try
    {
           using (TextWriter writer = new StreamWriter(path, false))
           {
                 XmlSerializer ser = new XmlSerializer(typeof(Class1) );
                 ser.Serialize(writer, db);
                 writer.Close();
            }
    }
    catch (Exception ex)
    {
            int toto = 0;
    }

    La InnerException est :
    The type MonProjet.Class3 was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically.

    Merci d'avance



    EDIT : Pour info, je peux sérialiser un objet Class3 et une liste d'objets Class3, mais pas de liste de Class2, ni (en toute logique) d'objet Class1.

  6. #6
    Membre émérite
    Avatar de laedit
    Homme Profil pro
    Consultant études et développement
    Inscrit en
    Décembre 2006
    Messages
    1 344
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consultant études et développement
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 344
    Points : 2 265
    Points
    2 265
    Par défaut
    Sinon, si tu as accès à LINQ, tu peux utiliser LinqToXml et te faire ta méthode de sérialisation à la main et qui prendrais un objet en paramètre.

    Il te suffirait de parcourir ses données pour ensuite les écrire dans un fichier.
    Blog - Articles - Framework

    MSDN vous aide, si si, alors n'hésitez pas à y faire un tour avant de poser une question.
    Ah, et n'oubliez pas, Google peut répondre à la majorité de vos questions.

  7. #7
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    J'ai l'impression que tu t'es un peu embrouillé sur l'utilisation de l'attribut XmlInclude...

    Pour rappel, voilà comment ça marche

    Il est inutile d'appliquer l'attribut [XmlInclude(typeof(Class1)] sur Class1, c'est implicite. Idem pour Class2 et Class3 : le type étant connu statiquement, l'utilisation de XmlInclude n'apporte rien.

    Par contre, une liste de Class2 peut contenir des objets Class3, alors que XmlSerializer s'attend à ne rencontrer que des objets Class2. Donc le seul endroit où il faut utiliser l'attribut XmlInclude, c'est pour indiquer sur Class2 que le sérialiseur peut aussi avoir à traiter des objets Class3 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    [XmlInclude(typeof(Class3))] 
    public abstract class Class2
    ...

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    95
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 95
    Points : 62
    Points
    62
    Par défaut
    Citation Envoyé par tomlev Voir le message
    J'ai l'impression que tu t'es un peu embrouillé sur l'utilisation de l'attribut XmlInclude...

    Pour rappel, voilà comment ça marche

    Il est inutile d'appliquer l'attribut [XmlInclude(typeof(Class1)] sur Class1, c'est implicite. Idem pour Class2 et Class3 : le type étant connu statiquement, l'utilisation de XmlInclude n'apporte rien.

    Par contre, une liste de Class2 peut contenir des objets Class3, alors que XmlSerializer s'attend à ne rencontrer que des objets Class2. Donc le seul endroit où il faut utiliser l'attribut XmlInclude, c'est pour indiquer sur Class2 que le sérialiseur peut aussi avoir à traiter des objets Class3 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    [XmlInclude(typeof(Class3))] 
    public abstract class Class2
    ...
    Excellent merci, j'avais trouvé en lisant votre très bon cours sur la sérialisation. Merci à tous pour votre aide

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [C#] Comment passer mon propre objet à la méthode Web ?
    Par mimibobo dans le forum Services Web
    Réponses: 6
    Dernier message: 05/10/2006, 10h08
  2. en configurant mon easyphp j'ai bloqué mon propre IP
    Par boogieboy dans le forum Apache
    Réponses: 2
    Dernier message: 02/04/2006, 19h14
  3. Réponses: 6
    Dernier message: 17/01/2006, 15h53
  4. Réponses: 4
    Dernier message: 13/08/2005, 10h20
  5. [apache] probleme d'accès à mon propre serveur
    Par sunfunfree dans le forum Apache
    Réponses: 6
    Dernier message: 15/02/2005, 16h16

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