Serialization and optional elements

Using a new feature called Version Tolerant Serialization in .NET 2, it becomes possible to change class definitions and still deal with old serialized data versions after an application has been updated. This is actually extremely easy to do. Consider this code:

[Serializable]
public class Test {
  string name;
  public string Name {
    get { return name; }
    set { name = value; }
  }
}

Now say you have deployed version 1 of your application with this class definition and used serialization to save instances of class Test to some kind of storage. Users of your application have megabytes of data stored away in that specific format.

Now you continue developing your application and you find the need to add properties to Test. The problem is, once you do that, you’ll no longer be able to deserialize the earlier version of the class, resulting in huge data loss for your users! Version Tolerant Serialization is the feature that comes to the rescue here. You can now define your new class version like this:

[Serializable]
public class Test {
  string name;
  public string Name {
    get { return name; }
    set { name = value; }
  }

  int newVal;
  [OptionalField]
  public int NewVal {
    get { return newVal; }
    set { newVal = value; }
  }

  bool marker;
  [OptionalField]
  public bool Marker {
    get { return marker; }
    set { marker = value; }
  }

  [OnDeserializing]
  void Deserializing(StreamingContext context) {
    // We get here before data is actually written to our properties
    // So we set some default values for the optional properties.

    newVal = 42;
    marker = false;
  }

  [OnDeserialized]
  void Deserialized(StreamingContext context) {
    // We get here when data has been written to all the properties
    // that were found during deserialization, which may not have been
    // all we have in case an old storage format was used.
    // So we can now analyze what's happened and fix up what's necessary.

    if (!marker) {
      // . . .
    }
  }
}

In many cases, dedicated fixup code may not really be necessary, but it’s certainly possible to work with older data definitions in this way, at least for most kinds of changes. There are also corresponding attributes OnSerializing and OnSerialized, in case a hook into the serialization process is needed as well.

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s