Windows Develop Bookmark and Share   
 index > Windows Forms Designer > serializing object to resources across versions?
 

serializing object to resources across versions?

I am trying to implement an object which gets saved to the resources for the form at design-time and loaded back into a property for a custom control.  That is not a problem; using the DesignerSerializationVisibility attribute with DesignerSerializationVisibility.Visible on the property in the control that gets and sets the object, the default CodeDomSerializer for windows forms controls will serialize the object to the form resources and generate code to load it back into the property on the control in the InitializeComponent method.

The problem is getting that serialized object in the form resources to load back in after changing the version number of the assembly.  After changing the version number in the AssemblyInfo source file, a test project that was created with an earlier version of the control dll will no longer load the object from the resources, even though nothing else has changed in the code.

I have tried implementing ISerializable on the object, and the magic constructor does not even get called with the newer version of the assembly.  It appears that the default CodeDomSerializer for windows forms controls is rejecting the SerializationInfo for the object because the version number does not match the version number of the object that was saved.

This is a real problem for anyone who wants to publish controls that save objects to the resources (which may be necessary for immutable objects that cannot use Content serialization), maintain their code with updates that have higher version numbers (which is absolutely necessary to distinguish between releases), and maintain backwards compatibility with earlier releases (which is absolutely necessary for customer support).  Customers will not like losing their design-time settings when they install a maintenance release.

The documentation states very clearly that this should work.  In the help topic for Binary Serialization - Versioning, it says "The .NET Framework provides support for versioning and side-by-side execution, and all classes will work across versions if the interfaces of the classes remain the same."
 
I have tested this with the Visual Studio 2003 beta, and it appears to be fixed there, but the problems still appears in Visual Studio 2002 with the service packs for VS.Net and the framework installed.  For this reason, I believe this is a bug in the framework version 1.0.3705 and earlier, but I hope that maybe I am wrong about that.

Does anyone know of a way to get these objects in the resources to load back into a newer version of the assembly using System.Design.dll version 1.0.3705?  Is there some attribute that is not mentioned in the documentation under Binary Serialization - Versioning that is required to make this work?

-Sean
MigrationUser 1  Friday, March 07, 2003 12:52 PM
OK, I have no idea whether this will help, or if it's even a reasonable solution, but you can inform the serializer not to store the assembly information--set the AssemblyFormat property to FormatterAssemblyStyle.Simple. This definitely removes the assembly info from the serialized stream. Whether it will help in your situation, I can't tell you. But in case you hadn't noticed the option, I thought it worth mentioning...
MigrationUser 1  Saturday, March 08, 2003 10:34 AM
Not sure about what i'm going to say, but it could be a hint if i'm not mistakened and it applies to your problem

I think i read somewhere (not too sure where either) something about version numbers having minor and major compatibility ... well ..

If i change version from 1.0.0.0 to 1.0.0.1 ... things will still be fine but if i change from 1.0.0.0 to 1.1.0.0 things will stop working

Like i said, it could be related to something completely different but i thought it was worth mentioning just in case.
MigrationUser 1  Saturday, March 08, 2003 9:31 PM
Thanks, I will try that.

-Sean
MigrationUser 1  Monday, March 10, 2003 12:09 PM
It does not work even changing the build number from 1.0.0.0 to 1.0.0.1 (except in Visual Studio 2003).  I assumed that it would work for even major version changes, so that new major versions (2.x.x.x) can maintain backwards binary compatibility with old major versions (1.x.x.x).  I have not tested whether changes to the major version number will work in Visual Studio 2003.

-Sean
MigrationUser 1  Monday, March 10, 2003 12:15 PM
Did you try changing the AssemblyFormat property to not include this info? Just wondering if that didn't work for you.
MigrationUser 1  Tuesday, March 11, 2003 9:11 AM
Ken,

I do not see any way of getting or setting that property for the serialization formatter used by ControlCodeDomSerializer to serialize the object property to the form resources, even by replacing the serializer with my own using the DesignerSerializer attribute.  None of the methods in CodeDomSerializer pass a BinaryFormatter used for serializing objects to the form resources, and I do not see any methods in IDesignerSerializationManager for getting it either.

It does appear to work to change the assembly version from 1.0.0.0 to 2.0.0.0 in Visual Studio 2003.  The more I look into this problem, the more convinced I am becoming that it is a bug in the ControlCodeDomSerializer which has been fixed in VS 2003.

To give a better idea of what I am doing, here is some code that reproduces the behavior I am seeing:

using System;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.Serialization;
using System.Windows.Forms;

namespace SerializationAcrossVersions
{
  [Serializable()]
  public class TestObject : ISerializable
  {
    private string text;
    public TestObject()
    {
      text = "default";
    }
    public TestObject(SerializationInfo info, StreamingContext context)
    {
      text = info.GetString("text");
    }
    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
      info.AddValue("text", text);
    }
    [DefaultValue("default")]
    public string Text
    {
      get
      {
        return text;
      }
      set
      {
        text = value;
        OnTextChanged(EventArgs.Empty);
      }
    }
    public event EventHandler TextChanged;
    protected virtual void OnTextChanged(EventArgs e)
    {
      if( TextChanged != null )
        TextChanged(this, e);
    }
  } // class TestObject

  public class Test : Control
  {
    private TestObject testObject;
    public Test()
    {
      testObject = new TestObject();
      testObject.TextChanged += new EventHandler(OnTextChanged);
    }
    [TypeConverter(typeof(ExpandableObjectConverter))]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
    public TestObject TestObject
    {
      get
      {
        return testObject;
      }
      set
      {
        if( value != null )
        {
          testObject.TextChanged -= new EventHandler(OnTextChanged);
          testObject = value;
          testObject.TextChanged += new EventHandler(OnTextChanged);
        }
      }
    }
    protected override void OnPaint(PaintEventArgs e)
    {
      e.Graphics.DrawString(testObject.Text, Font, new SolidBrush(ForeColor), 0, 0);
    }
    private void OnTextChanged(object sender, EventArgs e)
    {
      Invalidate();
      Update();
    }
  } // class Test
} // namespace SerializationAcrossVersions

When that code is compiled into a SerializationAcrossVersions.dll with Visual Studio 2002 and the AssemblyInfo.cs for the project has "[assembly: AssemblyVersion("1.0.0.0")]", and then the control is used in a Windows Forms EXE test project and the Test.TestObject.Text property is changed, the TestObject gets serialized to the form resources.  When the assembly version number for SerializationAcrossVersions.dll is changed in any way and the dll recompiled, the project fails to load the TestObject from the form resources in Visual Studio 2002 (but it works in Visual Studio 2003).

-Sean
MigrationUser 1  Wednesday, March 12, 2003 2:57 PM

You can use google to search for other answers

Custom Search

More Threads

• How to implement Datasource property on custom controls?
• The type or namespace name IDump,TextProperty,RemoteFilePathProperty,SourceFileproperty,TransferPorotocolProperty,ValidityCheck,DestinationFileProperty could not be found (are you missing a using directive or an assembly
• MDI CHILD QUESTIOn
• How do I reference a control's properties?
• KB 912019
• how to save controls' properties into a physical file (creating forms/controls dynamically)?
• Deriving from abstract UserControls
• In the form designer I can't access objects which are on an other form.
• Hosting a designsurface within a designer
• Can one use glyphs to manage user-interface with something other than a full-feldged control