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

VB.NET Discussion :

[vb.net] Probleme de serialization


Sujet :

VB.NET

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 52
    Par défaut [vb.net 2.0] Probleme de serialization
    Bonjour
    voici mon probleme : g une classe Noeud qui surcharge la classe Treenode (serializable) et qui implemente ISerializable. Je voudrais serializer les objets de type Noeud avec toutes leurs infos. Est il possible de la faire sans tout redefinir (getObjectData, etc...) ou y a t'il un moyen plus rapide ?
    Merci

  2. #2
    Membre Expert
    Avatar de Mehdi Feki
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 113
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 113
    Par défaut
    Pourquoi tu veux personnaliser la serialisation ?
    Est-ce que le comportement de la serialisation par defaut ne te convient pas ?

    Normalement une des raisons pour peronnaliser la serialisation ( en utilisant l'interface ISerializable) est que la classe que tu veux deserialiser a subi des changements depuis qu'ellle a été serialisée. Est-ce ton cas ?

    Sinon si tu insiste d'implementer l'interface ISerializable alors tu seras mené (mais pas obligé : tu auras un warning lors de la compilation) d'implementer getObjectData qui va definir la comportement de la serialisation.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 52
    Par défaut
    En fait je veux serializer un treenode, mais en lui rajoutant une variable.

  4. #4
    Membre Expert
    Avatar de Mehdi Feki
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 113
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 113
    Par défaut
    Est-ce que t'a compris mon message ?

  5. #5
    Membre Expert
    Avatar de Mehdi Feki
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 113
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 113
    Par défaut
    Bon apparament non, donc pour te repondre plus clairement :

    Pourquoi ne pas mettre l'attribut [Serializable] à la classe Noeud au lieu d'implementer ISerializable ?

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 52
    Par défaut
    désolé du delais de ma réponse.

    merci Mehdi. Effectivement, suite a ton post, des recherches sur l'attribut [serializable] m'ont montré que nous etions pas clair sur son fonctionnement.

    je vais faire qq tests mais j'avais deja eu une erreur avec cet attribut sur ma classe pplus tot.

    je reviendrais poster apres les tests

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 52
    Par défaut
    J'ai essayé juste avec l'attribut <serializable()>. J'ai eu une erreur a la deserialization, donc j'ai du implementé le constructeur: sub new(info,context).
    Par contre je n'arrive pas a accéder aux membres de ma classe héritée dans ce constructeur (je n'ai pas les clefs)...
    et si j'appelle seulement le constructeur de la classe mere, je ne récupère pas mes membres (normal)

    la question reste: comment faire pour ne pas tout reimplementer "from scratch" (j'ai eu d'ailleurs quelque soucis en essayant) ...

  8. #8
    Membre Expert
    Avatar de Mehdi Feki
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 113
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 113
    Par défaut
    Peux-tu nous montrer ton code ou au moins les membre de chacune des classes

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 52
    Par défaut
    Voila une première version du code de la classe Noeud :

    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
    Imports System.Runtime.Serialization
    <Serializable()> Public Class Noeud
     
        Inherits TreeNode
     
        Public myMember As String = "test"
     
        Public Sub New(ByVal myText As String)
            MyBase.New(myText)
        End Sub
     
        Public Sub New(ByVal myText As String, ByVal mychildren As Noeud())
            MyBase.New(myText, mychildren)
        End Sub
     
        Public Sub New()
            MyBase.New()
     
        End Sub
    J'appelle la sérialisation dans une classe form1 comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
            Dim file As IO.FileStream = New IO.FileStream("z:\test.dat", IO.FileMode.Create)
            Dim serializer As BinaryFormatter = New BinaryFormatter
            Dim tempNode As Noeud
            tempNode = CType(TreeView1.Nodes(1), Noeud)
            serializer.Serialize(file, tempNode)
    Et la deserialisation comme ceci (toujours dans form1):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
            Dim file As IO.FileStream = New IO.FileStream("z:\test.dat", IO.FileMode.Open)
            Dim deserializer As BinaryFormatter = New BinaryFormatter
            Dim tempNode as Noeud   
            tempNode = CType(deserializer.Deserialize(file), Noeud)
    La j'obtiens une erreur (durant la désérialisation) me demandant d'implémenter le constructeur de deserialisation

    J'ai donc implémenté le constructeur comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
            Public Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
     
            MyBase.New(info, context)
            ' et la.... c'est le drame: je n'ai pas la clef
            'Me.myMember = info.GetString("XXXX")
     
        End Sub
    si j'essai avec "MyMember" comme clef, au moment de la déserialisation j'ai une erreur "TargetInvocationException" avec dans le InnerException "Member "myMember" was not found"


  10. #10
    Membre Expert
    Avatar de Mehdi Feki
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 113
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 113
    Par défaut
    Ca ne m'aide pas trop il me faut le code de TreeNode et l'exception exacte comme elle est affichée, normalment à part l'attribut Serializable , tu n'a besoin d'ajouter aucune ligne de code.

    En fait t'es en quelle version du framework ?

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 52
    Par défaut
    Suite a mes test:
    Si on rajoute juste l'attribut Serializable, ça marche très bien, sauf si:
    - la classe hérite d'une classe qui implémente ISerializable
    - tous les membres ne sont serializable.
    (j'ai testé sur des classes "ultra basiques" ce comportement)

    Mon probleme est que Treenode implémente ISerializable et que TreenodeCollection n'est pas serializable.

    avec le seul attribut <serialisable()> on est coincé....


    Donc à la déserialization d'un objet Noeud (qui hérite de Treenode), le constructeur new(info,context) de treenode est appelé et je ne récupère donc pas mes membres non hérité.
    j'ai donc du reimplementer getObjectData et ce fameux constructeur. j'ai fait quelques progres mais c'est la recuperation de l'arborescence avec l'heritage qui pose probleme...

    dur dur....


    PS : J'ai la version 2.0 du framework (titre edite)
    j'ai mis le code de la classe Noeud qui herite de treenode dans le post au dessus en version "juste attribut serializable" et "avec le constructeur necessaire à ISerializable.

    merci.

  12. #12
    Membre Expert
    Avatar de Mehdi Feki
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 113
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 113
    Par défaut
    J'ai du mal à suivre Balbo, donc tu parle du composant Web TreeNode qui constitue le TreeView

    C'est une autre histoire !! J'ai cru que c'etait toi qui a creer le type TreeNode.

  13. #13
    Membre Expert
    Avatar de Mehdi Feki
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 113
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 113
    Par défaut
    Est-ce que tu veux serialiser le control ( ce qui n'est pas une bonne idée ) ou les donnés du TreeNode ?

  14. #14
    Membre Expert
    Avatar de Mehdi Feki
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 113
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 113
    Par défaut
    Bon Voila une premiere Solution en attendant que je l'ameliore un peu ou totalement:

    Classe Noeud
    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
     
    <Serializable()> Public Class Noeud
        Inherits TreeNode
        Implements ISerializable
     
        Public MyName As String
     
        Public Sub New()
     
        End Sub
        Public Sub New(ByVal dirName As String)
            MyBase.New(dirName)
            MyName = dirName
        End Sub
     
        Protected Sub New(ByVal si As SerializationInfo, ByVal context As StreamingContext)
            Dim j As Integer = 1
            Name = MyName = CType(si.GetValue("MyName", GetType(Object)), String)
            Dim o As Object
            Dim i As Integer = 1
            While i <= (si.MemberCount - j)
                o = si.GetValue(i.ToString, GetType(Object))
                Nodes.Add(CType(o, TreeNode))
                i += 1
            End While
        End Sub
        Public Overridable Sub GetObjectData(ByVal si As SerializationInfo, ByVal context As StreamingContext)
            si.AddValue("MyName", MyName)
            Dim i As Integer = 1
            For Each o As Object In Nodes
                If o IsNot Nothing Then
                    si.AddValue(i.ToString, o)
                    i += 1
                End If
            Next
        End Sub
    End Class
    Code de Serialisation
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
            Dim treenode As Noeud = New Noeud("My Tree Node")
            treenode.Nodes.Add("1")
            treenode.Nodes.Add("2")
            treenode.Nodes.Add("3")
            treenode.Nodes.Add("4")
            Dim file As FileStream = New FileStream("c:\test.dat", System.IO.FileMode.Create)
            Dim serializer As BinaryFormatter = New BinaryFormatter
            serializer.Serialize(file, treenode)
            file.Close()
            Console.WriteLine("La TreeNode a été Serialisée")
            Console.Read()
    Code de Deserialisation
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
            Dim treenode2 As Noeud = New Noeud
            Dim fs As FileStream = New FileStream("c:\test.dat", FileMode.Open)
            Dim bf As BinaryFormatter = New BinaryFormatter
            treenode2 = CType(bf.Deserialize(fs), Noeud)
            fs.Close()
     
            Console.WriteLine("la TreeNode {0} a été deserialisée", treenode2.MyName)
     
            For Each tn As TreeNode In treenode2.Nodes
                Console.WriteLine(tn.Text)
            Next
            Console.Read()
    Voila j'espere que ca va t'aider
    A+

  15. #15
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 52
    Par défaut


    j'ai testé ton code avec un arbre avec trois niveaux de hierarchie et ça ne marche toujours pas. j'ai toujours l'erreur :

    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
    TargetInvocationException
    exception has been thrown by the target of of an Invocation
    
    InnerException : member "1" was not found
    
    StackTrace :    at System.RuntimeMethodHandle._SerializationInvoke(Object target, SignatureStruct& declaringTypeSig, SerializationInfo info, StreamingContext context)
       at System.RuntimeMethodHandle.SerializationInvoke(Object target, SignatureStruct declaringTypeSig, SerializationInfo info, StreamingContext context)
       at System.Reflection.RuntimeConstructorInfo.SerializationInvoke(Object target, SerializationInfo info, StreamingContext context)
       at System.Runtime.Serialization.ObjectManager.CompleteISerializableObject(Object obj, SerializationInfo info, StreamingContext context)
       at System.Runtime.Serialization.ObjectManager.FixupSpecialObject(ObjectHolder holder)
       at System.Runtime.Serialization.ObjectManager.DoFixups()
       at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
       at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
       at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)
       at WindowsApplication8.Form1.Button2_Click(Object sender, EventArgs e) in C:\Documents and Settings\fadamo\My Documents\Visual Studio 2005\Projects\WindowsApplication8\WindowsApplication8\Form1.vb:line 118
       at System.Windows.Forms.Control.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ButtonBase.WndProc(Message& m)
       at System.Windows.Forms.Button.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.Run(ApplicationContext context)
       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
       at WindowsApplication8.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:line 81
       at System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
    de mon coté j'avais utilisé un Arraylist( qui est serializable) pour stocker la collection des fils avec la meme erreur

    En fait, apres plusieurs tests, il me semble que la serialization ne se fait pas de maniere recursive. Elle est faite niveau par niveau : d'abord le tous les noeuds du 1er niveau, puis tous ceux du 2eme niveau, etc (sans une imbrication pere/fils) ...

    Je pense que le pb vient de la et que c'est pour ça que j'ai cette erreur a la deserialization quand je veux reconstruire l'arborescence...

    merci en tous cas... je me sens moins seul sur ce probleme... mais pas de solution encore...

  16. #16
    Membre Expert
    Avatar de Mehdi Feki
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 113
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 113
    Par défaut
    Bon voila je crois qu'il ya beaucoup plus simple et selon mes tests ca fonctionne, iul suffisait de surcharger les methodes de la classe de base. Supposons que Noeud a un entier dans ses proprtietes :

    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
     
    <Serializable()> Public Class Noeud
        Inherits TreeNode
     
        Public noeud_id As Integer
     
        Public Sub New()
        End Sub
     
        Public Sub New(ByVal id As Integer)
            noeud_id= id
        End Sub
     
        Protected Overrides Sub Serialize(ByVal si As System.Runtime.Serialization.SerializationInfo, ByVal context As System.Runtime.Serialization.StreamingContext)
            MyBase.Serialize(si, context)
            si.AddValue("id", noeud_id)
        End Sub
     
        Protected Sub New(ByVal si As SerializationInfo, ByVal context As StreamingContext)
            MyBase.New(si, context)
            noeud_id = DirectCast(si.GetValue("id", GetType(Integer)), Integer)
        End Sub
     
    End Class
    J'attends ton feedback

  17. #17
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 52
    Par défaut
    ok merci. Je vais tester cette methode Lundi. Je te tiens au courant des résultats dès que possible


  18. #18
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 52
    Par défaut
    Merci Mehdi. J'ai bien testé cette méthode et ça fonctionne très bien.

    Je te remercie de t'être penché sur ce problème, ça m'a beaucoup aidé

    A bientot

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

Discussions similaires

  1. Réponses: 19
    Dernier message: 31/10/2005, 15h04
  2. [VB.NET] Problème checkBox et datagrid
    Par jagdjg dans le forum ASP.NET
    Réponses: 5
    Dernier message: 23/04/2004, 08h53
  3. [VS.NET] Probleme d'ancrage
    Par krachunka dans le forum Visual Studio
    Réponses: 2
    Dernier message: 22/04/2004, 14h09
  4. [VB.Net] Probleme avec dialogues (confirm et alert)
    Par crackity_jones666 dans le forum ASP.NET
    Réponses: 5
    Dernier message: 26/11/2003, 22h05

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