Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
Serialization object graph
Message
De
10/03/2009 14:08:35
 
 
À
Tous
Information générale
Forum:
ASP.NET
Catégorie:
Code, syntaxe and commandes
Titre:
Serialization object graph
Versions des environnements
Environment:
C# 3.0
Divers
Thread ID:
01386954
Message ID:
01386954
Vues:
75
Hi,

I'm trying to get a clearer idea of how the object graph fits in when implementing the ISerializationSurrogate interface. The code below actually works - but in, to me, a rather weird way....
When the Serialize method executes the following sequence occurs:
ClassASurrogate.GetObjectData()
ClassBSurrogate.GetObjectData()
But the second call is only made if the 'info.AddValue("cB",o.a);' line in the ClassASurrogate.GetObjectData() is executed. Note that it is NOT called from this line itself but as a subsequent call from .Serialize()......

The .Deserialize() sequence is just as odd:
ClassBSurrogate.SetObjectData() (which populates the ClassA.Name correctly)
ClassASurrogate.SetObjectData() (which also has to populate the nested ClassA.Name - if this is not done then it's null)

I was hoping that I would not have to do anything specific in the GetObjectData() for ClassA in order for the ClassB instance to be serialized. If I remove the surrogate for ClassA and let the native serialization do the job then the ClassB surrogate is called automatically.....

Anyone know of any links that might clarify what's actually going on here?
Here's the code:
    [System.Serializable]
    public class ClassA
    {
        public string name;
        public ClassB a;

        public ClassA()
        {
            name = "Class A Instance";
            a = new ClassB();
            a.name = "Class B Instance";
        }
    }

    [System.Serializable]
    public class ClassB
    {
        public string name;
    }


    public class ClassASurrogate : ISerializationSurrogate
    {
        public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
        {
            ClassA o = (ClassA)obj;
            info.AddValue("n", o.name);
            info.AddValue("cB",o.a);
        }
        public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)
        {
            ClassA o = (ClassA)obj;
            o.name = (string)info.GetValue("n", typeof(string));
            //o.a = (ClassB)info.GetValue("cB", typeof(ClassB));
            return o;
        }
    }

    public class ClassBSurrogate : ISerializationSurrogate
    {
        public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
        {
            ClassB o = (ClassB)obj;
            info.AddValue("n", o.name);
        }

        public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)
        {
            ClassB o = (ClassB)obj;
            o.name = (string)info.GetValue("n", typeof(string));
            return o;
        }
    }
Tested using
            ClassA oo = new ClassA();
            BinaryFormatter b = new BinaryFormatter();
            SurrogateSelector ss = new SurrogateSelector();

            ClassASurrogate cas = new ClassASurrogate();
            ss.AddSurrogate(typeof(ClassA), new StreamingContext(StreamingContextStates.All), cas);

            ClassBSurrogate cbs = new ClassBSurrogate();
            ss.AddSurrogate(typeof(ClassB), new StreamingContext(StreamingContextStates.All), cbs);

            b.SurrogateSelector = ss;
            MemoryStream m = new MemoryStream();
            b.Serialize(m, oo);
            m.Position = 0;
            ClassA again = (ClassA)b.Deserialize(m);
Best,
Viv
Répondre
Fil
Voir

Click here to load this message in the networking platform