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.

Sorry, this blog does not support comments.

I used various blog hosting services since this blog was established in 2005, but unfortunately they turned out to be unreliable in the long term and comment threads were lost in unavoidable transitions. At this time I don't want to enable third-party services for comments since it has become obvious in recent years that these providers invariably monetize information about their visitors and users.

Please use the links in the page footer to get in touch with me. I'm available for conversations on Keybase, Matrix, Mastodon or Twitter, as well as via email.