none
Deserializing old versions RRS feed

  • Question

  • I'm having a hard time deserializing old versions of a class after adding a new member. I've written a toy program that's the simplest possible example of this problem. Maybe someone else might notice what I'm doing wrong.


    I have a class with one member: A System.Drawing.Color:


        [Serializable]

        public class SerialObj
        {
            public System.Drawing.Color color;
        }


    The following code serializes/deserializes it with no problem:

                SoapFormatter formatter = new SoapFormatter();     // Serialize:
                formatter.AssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple;
                formatter.Serialize(myStream, so);


                SoapFormatter formatter = new SoapFormatter();     // Deserialize:
                 formatter.AssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple;
                so = (SerialObj)formatter.Deserialize(myStream);


    I added an int member, and I'm trying to use the ISerializable interface to handle the different versions. This interface requires a constructor with two special parameters, and a GetObjectData method:

        [Serializable]
        public class SerialObj : ISerializable
        {
            public System.Drawing.Color color;
            public int number;                    // The new member.

            public SerialObj()
            {
                System.Windows.Forms.MessageBox.Show("In empty ctor.");
            }


            public SerialObj(SerializationInfo info, StreamingContext cntxt)
            {
                System.Windows.Forms.MessageBox.Show("In full ctor.");
                color = (System.Drawing.Color)info.GetValue("color", typeof(System.Drawing.Color));

                try

                {
                    number = info.GetInt32("number");
                }
                catch (Exception ex)
                {
                    System.Windows.Forms.MessageBox.Show(ex.Message);
                }
            }


            void ISerializable.GetObjectData(SerializationInfo inf, StreamingContext cxt)
            {
                System.Windows.Forms.MessageBox.Show("In GetObjectData.");
                inf.AddValue("color", color);
                inf.AddValue("number", number);
            }
        }


    It works for serialized new versions with both members. But when I deserialize an old version (without the int), it crashes on the Deserialize call, with the exception: "Top Object cannot be instantiated for element 'color'." It never even calls either constructor.

    Can anyone see what I'm doing wrong, or suggest an alternative approach?

    Thanks!
    Alan

    Monday, April 12, 2010 5:23 PM