Understanding Serialization in .NET

serialization in .netA complex software application interacts with multiple sources of data in order to achieve a particular functionality. For instance, a data centric application relies on a physical database located within or outside the application domain. A network centric application relies on data received via a network to perform a particular action. In .NET, most of the data communication is done via objects. Transferring or writing objects directly to a data source is not recommended owing to security reasons. For instance, a database record written directly to a database in the form of sequence of texts and characters is vulnerable. Anyone can read and exploit the data. Same is the case with a text file where data is stored in the form of strings of byte. Serialization resolves this issue.

Interested in learning more about C# .NET? Take a course at Udemy.com.

What is Serialization?

In .NET, serialization is the process of transforming built-in or custom defined data objects into streams of bytes for transferring them to a data source. The reverse of serialization is called deserialization which refers to the process of converting stream of bytes of data into actual object. This article explains the process of serializing a class, writing the content of the object of that class to a file, reading back the content of the file and desterilizing the content to again form the actual object.

Serialization in NET: A complete example

To further understand the concept of serialization. Follow along the steps in this section to create a custom class Person. The object of this Person class would be serialized and its content would be saved to some file in the form of stream of bytes. Then, via deserialization, the content of the files would be read and actual Person object would be constructed from the stream of bytes. All the code in the following example has been written in C#.

Step1:

Create a Simple C# class named Person, having two attributes: An integer type value named age and a string type value named name. The definition of the class should look like this:

[Serializable()]

class Person : ISerializable

{

public int age;

public string name;

}

To serialize the object of any class, two changes are required to be made in the class. Firstly, an attribute [Serializable()] must be added before the class declaration. Secondly, class must implement ISerializable interface.

Step 2:

Serialization Function:

Add the following method inside the Person class defined in Step1.

public void GetObjectData(SerializationInfo serobj, StreamingContext scontext)

{

serobj.AddValue("PersonAge", age);

serobj.AddValue("PersonName", name);

}

For serializing the properties of a class, the GetObjectData method of the ISerializable interface implemented by the Person class, has to be overridden. The GetObjectData method actually serializes the content of a class to streams. This method takes two parameters, a SerializationInfo and StreamingContext objects. When a Serialized method is called on the object BinaryFormatter class, this method is triggered.

An extremely important point to note here is that, inside the GetObjectData method, the AddValue method is called on the SerializationInfo object. This AddValue method is used to add variables that are to be serialized. Only those member variables are serialized which are added to the SerializationInfo object via AddValue method. In the above method, both of the two variables of the Person i.e. age and name has been added to the serialization info object serobj. The AddValue method takes a key value pair where the key denotes the serialized variable and the value denotes the class variable to be serialized.

Deserialization Constructor

To for deserializing the stream of bytes of an object from a resource, any method can be used but in this example, a constructor has been used to de-serialize the contents of the file. Add the following constructor in the Person class.

public Person(SerializationInfo serobj, StreamingContext scontext)

{

age = (int)serobj.GetValue("PersonAge", typeof(int));

name = (String)serobj.GetValue("PersonName", typeof(string));

}

The deserialization constructor also takes two parameters similar to the one in GetObjectData method but for deserialization purposes, the GetValue method is called on the SerializationInfo object. The GetValue method takes two parameters: one is the key with a value for retrieval and the second is the type of the value. It is worth noting that only those keys can be for deserialization that was used to serialize the variables of the object. For instance, a Key PersonAge was added using AddValue method; this key holds reference to age variable. To deserialize the value of age variable, the same key PersonAge has to be used.

To learn more about C#, look at courses at Udemy.com.

Step3:

To actually create the object of the Person class and to perform Serialization and Deserialization, the following code can be used:

Person person = new Person();

person.age = 30;

person.name = "James";

//Serialization Logic Starts

Stream writerstream = File.Open("D:\\PersonInfo.txt", FileMode.Create);

BinaryFormatter binformat = new BinaryFormatter();

Console.WriteLine("Writing Person Information");

binformat.Serialize(writerstream, person);

writerstream.Close();

// Serialization Logic Ends

// Deserialization Logic Starts

person = null;

Stream streamreader = File.Open("D:\\PersonInfo.txt", FileMode.Open);

binformat = new BinaryFormatter();

Console.WriteLine("Reading Person Information");

person = (Person)binformat.Deserialize(streamreader);

streamreader.Close();

// Deserialization Logic Ends

Console.WriteLine("Person Age: {0}", person.age.ToString());

Console.WriteLine("Person Name: {0}", person.name);

Console.ReadLine();

 

Stream type object streamwriter has been used to create a text file that will hold serialized content. Next, a BinaryFormatter object binformat has been instantiated. This Class is located in the System.Runtime.Serialization.Formatters.Binary namespace. The Serialize method of this class takes two parameters: The Stream object referring to the file to which serialized object contents are stored and the second parameter is the object to be serialized. The Serialize method actually triggers the GetObjectData method of the object to be serialized which is Person in this case.

To deserialize the contents of the object, the Deserialize method of same BinaryFormatter object can be employed but unlike the Serialize method, the Deserialize method takes only one parameter that is the Stream object which refers to the source from where the stream of bytes are to be read and deserialized. In the above method, the deserialized contents of the file are parsed into person object and the values of the age and name attributes have been displayed on console. These values would be similar to the one serialized to the text file.

For more interesting C# tutorials, look at a course at Udemy.com.