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 :

Interface ISerializable et cycles redondants


Sujet :

C#

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Par défaut Interface ISerializable et cycles redondants
    Bonjour à tous,

    Malgré moultes recherches sur le net, je n'arrive pas à trouver quelque chose de vraiment concret concernant l'interface ISerializable.
    J'aimerai pouvoir maitriser la serialisation de mes objets sans pour autant avoir à réécrire toute une classe me permettant de gérer les fichiers XML (lecture/ecriture). Pour cela, j'ai bien essayé la serialisation de base XML avec le XMLFormatter mais il y a un hic quand j'ai une relation cyclique entre mes objets. Par exemple, si j'ai un objet pere avec une liste d'enfants et que chacun a un lien vers le parent, le serializeur n'apprecie pas vraiment.
    Concernant l'interface ISerializable, j'ai mis en place la méthode GetObjectData mais je ne passe jamais dedans lorsque je serialise.

    Auriez vous un bon lien vers de la doc concernant cette interface ? J'ai bien vu l'exemple microsoft mais ils ont sorti le bazooka pour pas grand chose (cas d'un singleton...) et je n'y comprend pas grand chose...

    Merci d'avance

  2. #2
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Bonjour

    Citation Envoyé par zax-tfh Voir le message
    Par exemple, si j'ai un objet pere avec une liste d'enfants et que chacun a un lien vers le parent, le serializeur n'apprecie pas vraiment.
    Pour ce cas, il suffit de dire au serializer XML d'ignorer l'attribut/la propriété en question avec XmlIgnore. Mais ceci dit, en bonne logique une telle propriété devrait être en lecture seulement et donc ne poser aucun problème au moment de la sérialisation. Le serializer XML standard ne prend en effet en compte que les membres et propriétés publiques accessibles en lecture-écriture (contrairement au serializer binaire).

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Par défaut
    Merci pour ta réponse, j'y ai déjà pensé mais comment gère tu ensuite la relation du parent ? Car si tu ignores l'attribut, lors de la déserialisation, il ne refera pas la relation Pere de l'objet Enfant.

  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 : 43
    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
    Par défaut
    L'interface ISerializable (tout comme l'attribut Serializable) n'ont rien à voir avec la sérialisation XML, ils servent pour la sérialisation binaire ou SOAP.

    Si tu veux personnaliser la sérialisation XML, tu peux implémenter IXmlSerializable, mais c'est un peu galère...

    Sinon, pour ton problème spécifique, j'avais écrit un billet à ce sujet il y a quelque temps, regarde si ça peut t'aider

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Par défaut
    Salut Tomlev,

    Merci pour les liens, et apparement, la premiere solution, bien qu'un peu verbeuse, me parait la plus judicieuse dans mon cas
    Nickel chrome ! merci beaucoup

    @+

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Par défaut
    Par contre, petite question :
    Avec l'interface IXmlSerializable, j'ai implémenté tout ce qu'il fallait pour que la serialisation/deserialisation se passe nickel avec des objets pere/fils pour que les relations cycliques soient correctement gérées.
    Mais j'ai pu remarquer que le writer, par défaut utilise le nom de la classe pour créer l'élément XML. Sais tu s'il est possible de changer de nom pour en mettre un à notre sauce ? j'ai tenté de voir dans les dataannotations <XML... mais à priori elles ne s'appliquent pas à la déclaration de la classe.
    Aurais tu une idée sur le sujet ?
    Merci

  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 : 43
    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
    Par défaut
    Là comme ça je vois pas... tu peux montrer ton code ?

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Par défaut
    Eh bien le code est très simple :
    Tu créés une classe PersonneXYZ avec une propriété nom par exemple.
    Tu implémentes l'interface et tu fais en sorte de sérialiser la propriété nom en tant qu'attribut (pas besoin d'ajouter un noeud "Personne" car il est ajouté automatiquement).
    Lorsque tu vas serialiser tout ca, il va te faire un xml avec un élément <PersonneXYZ nom="toto" />

    La question qui me taraude c'est comment fait-on si on veut changer le nom de l'élément automatiquement généré pour avoir un truc dans le genre
    <Personne nom="toto" />

    Le pire c'est que ca ne se produit que sur le premier objet de l'arbre sérialisé car pour tous les descendants, c'est toi même qui définit le nom du noeud.

  9. #9
    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 : 43
    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
    Par défaut
    ah ok
    mets l'attribut XmlRoot sur la classe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    [XmlRoot("Personne")]
    public class PersonneXYZ
    {
        ...
    }

  10. #10
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Par défaut
    Merci bien ! je vais tester ca ce midi

  11. #11
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Par défaut
    Alors j'ai testé et ca fonctionne bien. Le problème c'est plutot la modularité.
    Imaginons que l'on veuille rendre le processus de serialisation autonome dans le sens où on souhaite pouvoir serialiser n'importe quel objet et ses descendants sans pour autant brider le point de départ à l'élément le plus haut, pour avoir quelque chose de modulable, la gestion des noeuds enfants se fait dans le parent. Je vais m'expliquer par un exemple :

    Voici trois classes reliées entre elles par une relation parent/enfant :

    Pere/Enfant/Jouet

    un pere a plusieurs enfants et chaque enfant a plusieurs jouets.
    Dans les fonctions de serialisation, on implémente le code permettant de serialiser les propriétés de base.
    Si on part du pere :
    Il ne doit serialiser que ses attributs puis, dans une boucle, doit serialiser chaque enfant.
    donc pour chaque enfant, on lance un e.writeXml(writer).
    Dans la méthode de serialisation de l'enfant, on doit créer un noeud enfant, serialiser les attributs classiques, traiter la serialisation des jouets, puis refermer le noeud enfant.

    Ce cas nous donne un fichier xml avec un noeud pere (le noeud est créé automatiquement par le processus de serialisation), avec tous les attributs du pere. A l'interieur de ce noeud on a une liste de noeuds enfant créés par la méthode de serialisation de l'objet enfant et ainsi de suite pour les jouets.

    Maintenant, si on souhaite serialiser un enfant tout en conservant le code décrit plus haut, on se retrouve avec un noeud enfant sans attribut, à l'interieur de celui ci un autre noeud enfant, ce coup ci avec les attributs, puis ensuite, la partie concernant les jouets.

    Le premier noeud enfant correspond à ce que le serializer créé automatiquement à partir du type de l'objet (ou alors de sa dataannotation XmlRoot) et le second correspond à l'insertion du noeud réalisée dans le code de serialisation de la classe enfant.

    Grosso modo, pour faire en sorte de contourner ce probleme, toute création de noeud doit se faire dans la partie parent (le pere doit créer les noeuds enfant, l'enfant doit créer les noeuds jouet alors que la logique voudrait plutot que ce soit chacun qui créé ses propres noeuds je suppose).

    Tout cela est du au décalage réalisé par le serializer qui va systématiquement créé un noeud pour l'objet en cours de sérialisation.

  12. #12
    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 : 43
    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
    Par défaut
    Comme je l'avais dit plus haut, implémenter IXmlSerializable c'est assez galère

  13. #13
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Par défaut
    En effet, mais finalement tu conserves la main mise sur la totalité du document (sauf le tout premier noeud). je trouve ca plutot pratique

  14. #14
    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 : 43
    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
    Par défaut
    Citation Envoyé par zax-tfh Voir le message
    En effet, mais finalement tu conserves la main mise sur la totalité du document (sauf le tout premier noeud). je trouve ca plutot pratique
    Ca dépend de ce que tu cherches... perso, pour moi le principal intérêt de la sérialisation XML est que ça gère tout à peu près automatiquement. A partir du moment où je dois le gérer à la main, je ne vois plus l'intérêt

  15. #15
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Par défaut
    Tu as raison, ca devient le binz quand tu as des references entre objets de même type.
    Un exemple : tu dois chainer des objets entre eux pour former une boucle fermée (o1->o2->o3->o1)
    Quand tu déserialise o1 tu as deux liens : un vers o2 et un vers o3 -> là ca coince
    Idem pour la serialisation, quand tu serialise o1, tu ne dois pas serialiser o2 et o3 en dessous de o1 mais au même niveau et ensuite jouer sur des references. Bref, c'est la misere le xml...

  16. #16
    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 : 43
    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
    Par défaut
    Citation Envoyé par zax-tfh Voir le message
    Tu as raison, ca devient le binz quand tu as des references entre objets de même type.
    Un exemple : tu dois chainer des objets entre eux pour former une boucle fermée (o1->o2->o3->o1)
    Quand tu déserialise o1 tu as deux liens : un vers o2 et un vers o3 -> là ca coince
    Idem pour la serialisation, quand tu serialise o1, tu ne dois pas serialiser o2 et o3 en dessous de o1 mais au même niveau et ensuite jouer sur des references. Bref, c'est la misere le xml...
    Eh oui... mais ça ce n'est pas spécifique à IXmlSerializable, c'est un problème général de la sérialisation XML. D'où la solution que j'avais postée pour la gestion des relations parent-enfant.

    Sinon, tu peux utiliser DataContractSerializer, qui sait gérer les références cycliques. Ca suppose que tu n'aies pas de contraintes sur le schéma XML, parce que ça ne permet pas de spécifier le schéma aussi précisément que XmlSerializer...

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

Discussions similaires

  1. [VB.NET] Interface ISerializable
    Par c4rr3r4 dans le forum VB.NET
    Réponses: 0
    Dernier message: 07/02/2011, 17h06
  2. [VB6] [Interface] ComboBox à plusieurs colonnes
    Par mtl dans le forum VB 6 et antérieur
    Réponses: 7
    Dernier message: 30/03/2004, 17h35
  3. [VB6] [Interface] Horloge 7 segments
    Par selenay dans le forum VB 6 et antérieur
    Réponses: 11
    Dernier message: 07/10/2002, 16h15
  4. interface utilisateur avec OpenGL
    Par demis20 dans le forum OpenGL
    Réponses: 6
    Dernier message: 03/10/2002, 12h27
  5. [VB6] [Interface] Icones de boutons de barre d'outils
    Par elifqaoui dans le forum VB 6 et antérieur
    Réponses: 9
    Dernier message: 13/09/2002, 15h50

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