Versioning Tolerance Serialization in .NET Framework 2.0

This article is based on .NET Framework 2.0 beta 1. This version of .NET Framework has new features called VTS (Versioning Tolerance Serialization). Before discussing this, allow me to define Serialization. Serialization is the process of saving or persisting the object state in to persistence. By using the Deserialization process, you can restore the object state back to where it was before Serialization. This process cycle is called Serialization.

A good example for the Serialization process is the Windows Paint application. You can use the Aaint application to draw any picture, after which, when you want to save this picture, the Paint application uses the serialization process to save the image to file as bytes. Later, if you want to open the saved image file, the Paint application uses the Deserialization process to restore the image.

In .NET Framework the System.Runtime.Serialization namespace provides Serialization-related classes. .NET Framework 1.1 provides two types of serialization formatters, namely Binary and SOAP. You can use SOAP formatters to persist the object state as a SOAP document, simply stored in XML format. Also, just by using the Attribute [Serializable], CLR can serialize the object.

Now, look at what VTS (Versioning Tolerance Serialization) is. Assume that you have created a class called profile. This class contains the following fields:

public class Profile
{
   private string name;
   private string emailAddress;
   private string phone;
   private string country;
}

and are serialized in binary format. Now, version the class defined above to be 1.0. Now you have added a few new fields, called cellPhone and title to that exisiting class, and called it Verison 2.0. The new version of the class looks like this:

public class Profile
   {
      private string name;
      private string emailAddress;
      private string phone;
      private string country;
      private string cellPhone;
      private string title;

  }

Now, if you try to deserialize the old class that is verison 1.0 by using the new class, an exception will be thrown because of a versioning problem. The new class has extra fields called cellphone and title. You can solve this problem now with .NET framework 2.0 by using the new OptionalFieldAttribute (added to System.Runtime.Serialization namespace in .NET 2.0).

Serializing the Profile Class 1.0

You can serialize the Profile class into binary format. For that, you need to import the following namepsace.

// specifying Binary formater.
using System.Runtime.Serialization.Formatters.Binary;

// for opening and creating files.
using System.IO;
// to access all Serilization related classes
using System.Runtime.Serialization ;


using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization.Formatters;
using System.IO;
using System.Runtime.Serialization ;
namespace ConsoleApplication1
{
   [Serializable]
   public class Profile
   {
      private string name;
      private string emailAddress;
      private string phone;
      private string country;


      public string Name
      {
         get
         {
            return name;
         }
         set
         {
            name = value;
         }
      }

      public string EmailAddress
      {
         get
         {
            return emailAddress;
         }
         set
         {
            emailAddress = value;
         }
      }

      public string Phone
      {
         get
         {
            return phone;
         }
         set
         {
            phone = value;
         }
      }

      public string Country
      {
         get
         {
            return country;
         }

         set
         {
            country = value;
         }
      }

   }
   class Program
   {
      static void Main(string[] args)
      {

         Profile profileobj = new Profile();
         profileobj.Name = "BABA";
         profileobj.EmailAddress = "BABA@Universe.com";
         profileobj.Phone = "9727173364";
         profileobj.Country = "India";

         FileStream fs = new FileStream(@"C:\\SavetoBinary",
                                        FileMode.Create);
         BinaryFormatter bfor = new BinaryFormatter();
         bfor.Serialize(fs, profileobj);
         fs.Close();

      }
   }
}

The above program will serialize the Profile object to binary format. Now, deserialize the Profile class version 1.0 with new Version 2.0; then, you will get a exception saying the following:

"Member \"cellPhone\" in class \"ConsoleApplication1.Profile\" is not present in the serialized stream and is not marked with System.Runtime.Serialization.OptionalFieldAttribute".

because there will be a versioning conflict. To solve this problem, you have to use versioning tolerance serailization (VTS). As I mentioned before, this could be done with the OptionalFieldAttribute. With the use of the OptionalFieldAttribute, the new profile class should look like this:

namespace ConsoleApplication1
{
   [Serializable]
   public class Profile
   {
      private string name;
      private string emailAddress;
      private string phone;
      private string country;
      [OptionalField(VersionAdded=2)]
      private string cellPhone;
      [OptionalField(VersionAdded = 2)]
      private string title;

      public string Name
      {
         get
         {
            return name;
         }
         set
         {
            name = value;
         }
      }

      public string EmailAddress
      {
         get
         {
            return emailAddress;
         }
         set
         {
            emailAddress = value;
         }
      }

      public string Phone
      {
         get
         {
            return phone;
         }
         set
         {
            phone = value;
         }
      }

      public string Country
      {
         get
         {
            return country;
         }

         set
         {
            country = value;
         }
      }

      public string CellPhone
      {
         get
         {
            return cellPhone;
         }

         set
         {
            cellPhone = value;
         }
      }

      public string Title
      {
         get
         {
            return title ;
         }

         set
         {
            title = value;
         }
      }

   }
   class Program
   {
      static void Main(string[] args)
      {
         try
         {
            BinaryFormatter soapF = new BinaryFormatter();
            FileStream fs1 = new FileStream(@"C:\\SavetoBinary",
                                           FileMode.Open);
            Profile ab1 = (Profile)soapF.Deserialize(fs1);
            Console.WriteLine("De-Serialization is Sucess");
         }
         catch (Exception ex)
         {
            Console.WriteLine(ex.Message);
         }


      }
   }
}

As you can see in the code above, the OptionalFieldAttribute is added to the new field, not to the property. After adding this Optional Filed Attribute, try deserializing the Profile class 1.0 against 2.0 without throwing an exception; it will be able to deserialize the Profile class.

The advantage of Versioning Tolerance serialization is this: Suppose you developed a software application that can be used to draw or design the CAR based on the given input parameters and be able to serialize or save to a file as a binary Image format. Now, after two years, you release a new version of same software, but this version will serialize the designed image with a few new attributes. If you had used VTS, you still could open or de-serialize the old version of the CAR design; it could open it with a new version of this software.

Apart from the OptionalFieldAttribute .NET Framework 2.0, VTS provides four more attributes for serialization. They are:

  • OnDeserializing—This event happens before deserialization
  • OnDeserialized—This event happens after deserialization
  • OnSerializing—This event happens before serialization
  • OnSerialized—This even happens after serialization. By using these new attributes, you can do some logic before and after serialization or when you do the deserialization.

You can use them to mark the methods that would be executed during the serialization and deserialization of the class.

Now, see how you can use the above events-based Serialization attributes. Here, I am going to use these Attributes to set default values before and after deserialization.

[OnDeserializing]
void OnDeserializing(StreamingContext context)
{
   CellPhone = "4170000000";
}


[OnDeserialized]
void OnDeserializedProfile(StreamingContext context)
{
   title  = "Spiritual Leader";
}


About the Author

SeenivasaRagavan Ramadurai

Seenivasaragavan Ramadurai is a .NET consultant, He has been working with .NET technology since pre beta releases. Seenivasa background includes Master's in Computer Science and B.Sc. Mathematics. He has over 9 years of software development experience with Microsoft technologies and has extensive experience developing client-server, distributed, Web services, and component based applications using Visual Studio .NET. Before moving to .NET, Seenivasa has worked on MFC, COM, ATL, and Visual C++ based applications. If you are looking for a consulting help, contact him at skbbaba23@gmail.com

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Java developers know that testing code changes can be a huge pain, and waiting for an application to redeploy after a code fix can take an eternity. Wouldn't it be great if you could see your code changes immediately, fine-tune, debug, explore and deploy code without waiting for ages? In this white paper, find out how that's possible with a Java plugin that drastically changes the way you develop, test and run Java applications. Discover the advantages of this plugin, and the changes you can expect to see …

  • On-demand Event Event Date: September 10, 2014 Modern mobile applications connect systems-of-engagement (mobile apps) with systems-of-record (traditional IT) to deliver new and innovative business value. But the lifecycle for development of mobile apps is also new and different. Emerging trends in mobile development call for faster delivery of incremental features, coupled with feedback from the users of the app "in the wild." This loop of continuous delivery and continuous feedback is how the best mobile …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds