Object Serialization Using .NET

Serialization is the process of writing the state of an object to a byte stream.


OR


Object Serialization is the process of reducing the objects instance into a format that can either be stored to disk or transported over a Network.

Serialization is useful when you want to save the state of your application to a persistence storage area. That storage area can be a file. At a later time, you may restore these objects by using the process of deserialization. In this article, you will learn about serialization and why you need serialization in .NET.

Initially, I will show you how to serialize objects to streams using the binary formatters. Later, you will serialize these objects using SOAP formatters and you will save your objects as XML files.

Before .NET, developers wasted a lot of precious time in writing code for serialization. Cerialization was possible before .NET; however, it was very time-consuming code work. Also, the methods prior to .NET were proprietary; there was no generic way of sharing serialized files. Now, developers can simply make call to the standardized methods whenever they want to serialized or deserialzed objects. The classes that are required to serialized object are available in the System.Runtime.Serializable namespace.

About Serialization in .NET

.NET objects are serialized to a stream. Developers must use a .NET formatter class to control the serialization of the object to and from the stream. In addition to the serialized data, the serialization stream carries information about the object’s type, including its assembly name, culture, and version.

Working with Formatters

A formatter is used to determine the serialization format for objects. All formatters expose an interface called the IFormatter interface. Two formatters inherit from the IFormatter interface and are provided as part of the .NET framework. These are the Binary formatter and the SOAP formatter.

The Binary Formatter

The Binary formatter provides binary encoding for compact serialization either for storage or for socket-based network streams. The BinaryFormatter class is generally not appropriate when data is meant to be passed through a firewall.

The SOAP Formatter

The SOAP formatter provides formatting that can be used to enable objects to be serialized using the SOAP protocol. The Soap Formatter class is primarily used for serialization through firewalls or among diverse systems.

Other Formatters

The .NET framework also includes the abstract FORMATTERS class that can be used as a base class for custom formatters. This class inherits from the IFormatter interface.

The Requirements for Serialization

Serialization is done so that the object can be recreated with its current state at a later point in time or at a different location. The following are required to Serialize an object:

  • The object that is to serialized itself.
  • A stream to contain the serialized object.
  • A Formatter used to serialize the object.

System.Runtime.Serialization is the namespace that contains the classes that are required to serialize an object.

To deserialize an object, the DeSerialize() method of the BinaryFormatter class is used.

Serializing an Object Using the Binary Formatter

I’ll present a case study using ACME Corporation. Within the example, you should read the comments to clearly understand what is happening.

Ali Sufyan is an IT strategist for ACME Corporation. He needs a way to store the state of his objects to disk. The company uses C# to code its internal system applications. The application contains a class called PayRoll, which consists of the members like this:

MEMBER NAME

TYPE

uName

Property

uId Property
eName Property
eSal Property
CalcHRA() Method
CalcPF() Method
Deductions Property
NetSal Property

Sufyan wants to save the state of his object at any point in his program. You will help him mark the class as Serializable and persist the properties of the class to disk using the binary formatter.

using System;
namespace SufyanTestClass
{
   // We are creating a simple class named SerialFor and to make
   // that class serializable we added an attribute [Serializable].
   // This attribute makes the class ready for Serialization

   [Serializable]
   public class SerialFor
   {
     /* [NonSerialized] attribute is used to make a method
      * non-Serializable in a serializable envoironment. The
      * condition is that Sufyan wants to make the property uname
      * and uid non-serializable. While the remaining class remains
      * serialized */

   [NonSerialized]
   public string uname;
   [NonSerialized]
   public int uid;
   public string ename;
   public int esal;
   public int calcHRA(int a,int b)
   {
      return (a-b);
   }

      public int CalcPF(int a,int b)
      {
         return (b-a);
      }

      public int Deductions;
      public int NetSal;
   }
}

Build the project as a class library. To make your project a class library, you go to solution explorer, right-click the Project, select Properties and change the OutPut Type to class library. When you build the project a .dll file is created in the debug folder of your projects directory.

Now, open another project in which you will serialize this class. Add a reference to the DLL created by the previous code. You then can create the class with the following code:

using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

namespace SerialsufyanTestClass
{
   class Class1
   {

      [STAThread]
      static void Main(string[] args)
      {
         SufyanTestClass.SerialFor obj= new
                                        SufyanTestClass.SerialFor();
         obj.Deductions=90;
         obj.NetSal=1000;
         Stream a= File.OpenWrite("C:\abc.bin");
         BinaryFormatter bf=new BinaryFormatter();
         bf.Serialize(a,obj);
         a.Close();
      }
   }
}

This listing will create a file named abc.bin. on the C: drive. We are serializing the whole class to the file as well as adding value to deductions and NetSal to the file. We will use this in the next example.

The above code serializes the class. Now, you will deserialize the same class:

using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

namespace SerialsufyanTestClass
{
   class Class1
   {
      [STAThread]
      static void Main(string[] args)
      {
         FileStream file=new FileStream( "C:\abc.bin",
                                         FileMode.Open);

         BinaryFormatter bf=new BinaryFormatter();
         SufyanTestClassForSerialization.SerialFor obj =
               bf.Deserialize(file) as
         SufyanTestClassForSerialization.SerialFor;
         Console.WriteLine(obj.Deductions);
         Console.WriteLine(obj.NetSal);
         Console.WriteLine(obj.calcHRA());
         Console.ReadLine();
      }
   }
}

This code will deserialize the class and calculates the HRA based on the values of Deductions and NetSal we have serialized to the file.

Using SOAP TO Serialize and Deserialize

Using a SOAP protocol to serialize and deserialize your code is more or less the same as above. A little change will be required. You have to add a reference to System.Runtime.Serialization.Formatters.Soap in your Application.

The following is a repeat the above serialize and deserialize code. However, this time it uses SOAP. The main benefit of SOAP Serialization is portability. You can share the serialization information with any other application on any platform.

using System;
using System.Runtime.Serialization.Formatters.Soap;
usingSystem.IO;
namespace SerialsufyanTestClass
{
   class Class1
   {
      [STAThread]
      static void Main(string[] args)
      {
         SufyanTestClass.SerialFor obj=
               newSufyanTestClass.SerialFor();
         obj.Deductions=90;
         obj.NetSal=1000;
         Stream a=File.OpenWrite("C:\abc.ex");

         SoapFormatter bf=new SoapFormatter();
         bf.Serialize(a,obj);
         a.Close();
      }
   }
}

Deserializing Using SOAP

using System;
using System.Runtime.Serialization.Formatters.Soap;
using System.IO;

namespace {
classClass1
{static void Main(string[] args)
   {
      FileStream file=new FileStream( "C:\abc.ex", FileMode.Open);
      SoapFormatter bf=new SoapFormatter();
      SufyanTestClassForSerialization.SerialFor obj =
            bf.Deserialize(file) as
            SufyanTestClassForSerialization.SerialFor;
      Console.WriteLine(obj.Deductions);
      Console.WriteLine(obj.NetSal);
      Console.WriteLine(obj.calcHRA());
      Console.ReadLine();
   }
}

.NET Serialization & Object References

If a class that is to be serialized contains references to objects of other classes, and if those classes have been marked as serializable, then their objects are serialized too.

.NET serializes the objects state including the members of the base class or base classes. All members are serialized, including private or protected members. .NET knows their existence from the object’s metadata and accesses these members using reflection.

If the object has member variables that are serializable, then those members are serialized too. .NET serialization handles cyclic references, too. During the recursive serialization, even if one of the objects members (or one of the nested members) is not serializable, .NET throws a runtime exception. You must, however, ensure that all the base classes are serializable when you mark the class as serializable otherwise you might get unexpected results.

Suppose you want to make a Windows form application serializable. You can create the DLL, but when you try to make the form application serializable through binary or soap formatters, an exception will be raised stating that the base class is not marked as serializable. The System.Windows.Forms base class is not Serializable, so you can’t your forms application Serializable.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read