Introduction
Serialization is a process of converting an object into a stream of data so that it can be easily transmittable over the network or can be continued in a persistent storage location. This storage location can be a physical file, database or ASP.NET cache.
Serialization is the technology that enables an object to be converted into a linear stream of data that can be easily passed across process boundaries and machines. This stream of data needs to be in a format that can be understood by both ends of a communication channel so that the object can be serialized and reconstructed easily. The advantage of
serialization is the ability to transmit data across the network in a cross-platform-compatible format, as well as saving it in a persistent or non-persistent storage medium in a non-proprietary format.
Serialization is used by Remoting, Web Services SOAP for transmitting data between a server and a client. De-
serialization is the reverse; it is the process of reconstructing the same object later. The Remoting technology of .NET makes use of
serialization to pass objects by value from one application domain to another.
In this article, I will discuss .NET's support for
Serialization and how we can build a class that supports custom
serialization.
What is Serialization and De-Serialization?
Serialization is the process of saving the state of an object in a persistent storage media by converting the object to a linear stream of bytes. The object can be persisted to a file, a database or even in the memory. The reverse process of
serialization is known as de-
serialization and enables us to re-construct the object from the previously serialized instance of the same in the persistent or non-persistent storage media.
Serialization in .NET is provided by the
System.Runtime.Serialization
namespace. This namespace contains an interface called
IFormatter
which in turn contains the methods Serialize and De-serialize that can be used to save and load data to and from a stream. In order to implement
serialization in .NET, we basically require a stream and a formatter. While the stream acts as a container for the serialized object(s), the formatter is used to serialize these objects onto the stream.
The basic advantage of
serialization is the ability of an object to be serialized into a persistent or a non-persistent storage media and then reconstructing the same object if required at a later point of time by de-serializing the object. Remoting and Web Services depend heavily on
Serialization and De-
serialization.
Advantages and Disadvantages of Serialization
The following are the basic
advantages of
serialization:
- Facilitate the transportation of an object through a network
- Create a clone of an object
The primary disadvantage of
serialization can be attributed to the resource overhead (both the CPU and the IO devices) that is involved in serializing and de-serializing the data and the latency issues that are involved for transmitting the data over the network. Further,
serialization is quite slow. Moreover, XML
serialization is insecure, consumes a lot of space on the disk and it works on
public
members and
public
classes and not on the
private
or
internal
classes. Therefore, it compels the developer to allow the class to be accessed by the outside world.
The Serializable Attribute
In order for a class to be serializable, it must have the attribute
SerializableAttribute
set and all its members must also be serializable, except if they are ignored with the attribute
NonSerializedAttribute
. However, the
private
and
public
members of a class are always serialized by default. The
SerializationAttribute
is only used for binary
serialization. The code snippet below shows the usage of
SerializableAttribute
.
Collapse | Copy Code
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
namespace DemoSerialization
{
[Serializable]
public class Employee
{
public int empCode;
public string empName;
[XmlAttribute(empName)]
public string EmpName
{
get
{
return empName;
}
set
{
empName = value;
}
}
}
}
Note the
Serializable
attribute that is specified at the beginning of the class in the code listing above. The
SerializableAttribute
is useful for situations where the object has to be transported to other application domains. It needs to be applied even irrespective of whether the class implements the
ISerializable
interface. If this attribute is not set in that case, then when we try to serialize an object, the CLR throws a
SerializationException
.
Types of Serialization
Serialization can be of the following types:
- Binary Serialization
- SOAP Serialization
- XML Serialization
All these types of
serialization are explained in detail in the sections that follow.
Binary Serialization
Binary
serialization is a mechanism which writes the data to the output stream such that it can be used to re-construct the object automatically. The term binary in its name implies that the necessary information that is required to create an exact binary copy of the object is saved onto the storage media.
A notable difference between Binaryserialization and XML serialization is that Binary serialization preserves instance identity while XML serializationdoes not. In other words, in Binary
serialization the entire object state is saved while in XML
serialization only some of the object data is saved. Binary
serialization can handle graphs with multiple references to the same object; XML
serialization will turn each reference into a unique object. The following code listing shows how we can implement binary
serialization.
Collapse | Copy Code
#region Binary
private void btnBSerialize_Click(object sender, EventArgs e)
{
Employee emp=new Employee();
emp.empCode=Convert.ToInt16(txtbEmpCode.Text);
emp.EmpName=txtBEmpName.Text;
BinarySerialize(txtBinary.Text, emp);
MessageBox.Show(Binary Serialize Done!);
}
private void btnBDSerialize_Click(object sender, EventArgs e)
{
Employee emp = new Employee();
emp = (Employee)BinaryDeserialize(txtBinary.Text);
lblBEmpCode.Text =Emp Code: + Convert.ToString(emp.empCode);
lblBEmpName.Text = Emp Name: + emp.EmpName;
}
public void BinarySerialize(string filename, Employee emp)
{
FileStream fileStreamObject;
fileStreamObject = new FileStream(filename, FileMode.Create);
BinaryFormatter binaryFormatter = new BinaryFormatter();
binaryFormatter.Serialize(fileStreamObject, emp);
fileStreamObject.Close();
}
public static object BinaryDeserialize(string filename)
{
FileStream fileStreamObject = new FileStream(filename, FileMode.Open);
BinaryFormatter binaryFormatter = new BinaryFormatter();
object obj = (object)binaryFormatter.Deserialize(fileStreamObject);
fileStreamObject.Close();
return obj;
}
#endregion
Advantages and Disadvantages of BinarySerialization
One of the major
advantages of using Binary
Serialization in the managed environment is that the object can be de-serialized from the same data you serialized it to. Besides, the other advantage of Binary
Serialization is enhanced performance as it is faster and even more powerful in the sense that it provides support for complex objects, read only properties and even circular references. However, the downside to this is that it is not easily portable to another platform.
SOAP Serialization
The SOAP protocol is ideal for communicating between applications that use heterogeneous architectures. In order to use SOAP
serialization in .NET we have to add a reference to
System.Runtime.Serialization.Formatters.Soap
in the application. The basic advantage of SOAP
serialization is portability. The
SoapFormatter
serializes objects into SOAP messages or parses SOAP messages and extracts serialized objects from the message. The following code listing shows how we can implement
serializationusing the SOAP protocol:
Collapse | Copy Code
#region SOAP
private void btnSSerialize_Click(object sender, EventArgs e)
{
Employee emp = new Employee();
emp.empCode = Convert.ToInt16(txtSEmpCode.Text);
emp.EmpName = txtSEmpName.Text;
SOAPSerialize(txtSoap.Text, emp);
MessageBox.Show(SOAP Serialize Done!);
}
private void btnSDeSerialize_Click(object sender, EventArgs e)
{
Employee emp = new Employee();
emp = (Employee)SOAPDeserialize(txtSoap.Text);
lblSEmpCode.Text = Emp Code: + Convert.ToString(emp.empCode);
lblSEmpName.Text = Emp Name: + emp.EmpName;
}
public void SOAPSerialize(string filename, Employee employeeObject)
{
FileStream fileStreamObject = new FileStream(filename, FileMode.Create);
SoapFormatter soapFormatter = new SoapFormatter();
soapFormatter.Serialize(fileStreamObject, employeeObject);
fileStreamObject.Close();
}
public static object SOAPDeserialize(string filename)
{
FileStream fileStreamObject = new FileStream(filename, FileMode.Open);
SoapFormatter soapFormatter = new SoapFormatter();
object obj = (object)soapFormatter.Deserialize(fileStreamObject);
fileStreamObject.Close();
return obj;
}
#endregion
XML Serialization
According to MSDN, "XML
serialization converts (serializes) the
public
fields and properties of an object or the parameters and returns values of methods, into an XML stream that conforms to a specific XML Schema definition language (XSD) document. XML
serialization results in strongly typed classes with
public
properties and fields that are converted to a serial format (in this case, XML) for storage or transport. Because XML is an open standard, the XML stream can be processed by any application, as needed, regardless of platform." Implementing XML
Serialization in .NET is quite simple. The basic class that we need to use is the
XmlSerializer
for both
serialization and de-
serialization. The Web Services use the SOAP protocol for communication and the return types and the parameters are all serialized using the
XmlSerializer
class. XML
Serialization is however, much slower compared to Binary
serialization. We can set a property as an XML attribute as shown in the code listing below.
Collapse | Copy Code
#region Xml
private void btnXSerialize_Click(object sender, EventArgs e)
{
Employee emp = new Employee();
emp.empCode = Convert.ToInt16(txtXEmpCode.Text);
emp.EmpName = txtXEmpName.Text;
XMLSerialize(txtXml.Text, emp);
MessageBox.Show(Xml Serialize Done!");
}
private void btnXDeSerialize_Click(object sender, EventArgs e)
{
Employee emp = new Employee();
emp = (Employee)XMLDeserialize(txtXml.Text);
lblXEmpCode.Text = Emp Code:" + Convert.ToString(emp.empCode);
lblXEmpName.Text = Emp Name:" + emp.EmpName;
}
public void XMLSerialize(String filename, Employee emp)
{
XmlSerializer serializer = null;
FileStream stream = null;
serializer = new XmlSerializer(typeof(Employee));
stream = new FileStream(filename, FileMode.Create, FileAccess.Write);
serializer.Serialize(stream, emp);
if (stream != null)
stream.Close();
}
public static Employee XMLDeserialize(String filename)
{
XmlSerializer serializer = null;
FileStream stream = null;
Employee emp = new Employee();
serializer = new XmlSerializer(typeof(Employee));
stream = new FileStream(filename, FileMode.Open);
emp = (Employee)serializer.Deserialize(stream);
if (stream != null)
stream.Close();
return emp;
}
#endregion
Advantages of XML Serialization
The
advantages of XML
Serialization are as follows:
- XML based
- Support for cross platforms
- Easily readable and editable
Working with Formatters
A formatter is used to determine the
serialization format for objects. In other words, it is used to control the
serialization of an object to and from a stream. They are the objects that are used to encode and serialize data into an appropriate format before they are transmitted over the network. They expose an interface called the
IFormatter
interface.
IFormatter
's significant methods are Serialize and De-serialize which perform the actual
serialization and de-
serialization. There are two formatter classes provided within .NET, the
BinaryFormatter
and the
SoapFormatter
. Both these classes extend the
IFormatter
interface.
The Binary Formatter
The Binary formatter provides support for
serialization using binary encoding. The
BinaryFormater
class is responsible for binary
serialization and is used commonly in .NET's Remoting technology. This class is not appropriate when the data is supposed to be transmitted through a firewall.
The SOAP Formatter
The SOAP formatter provides formatting that can be used to serialize objects using the SOAP protocol. It is used to create a Soap envelop and it uses an object graph to generate the result. It is responsible for serializing objects into SOAP messages or parsing the SOAP messages and extracting these serialized objects from the SOAP messages. SOAP formatters in .NET are widely used by the Web Services.
Points to Remember
This section deals with some of the points that we have already covered in this article and some others that we have not, but are still very important and relate to the
serialization and de-
serialization concepts of .NET. When you apply the
Serializable
custom attribute to a type, all instance fields of the class (
public
,
private
,
protected
, etc.) are serialized automatically.
XmlSerializer
does not use the
ISerializable
interface; rather, it uses the
IXmlSerializable
interface. The
XmlSerializer
class can only serialize the
public
properties of the class, whereas the
BinaryFormatter
class can serialize
private
fields using the
ISerializable
interface.
The
Serializable
attribute is a must for making a class serializable irrespective of whether we have implemented the
ISerializable
interface in this class. When we serialize a class, the objects of the references to other classes that are contained in this class are also serialized if they are marked as serializable. All members are serialized, including
public
,
private
or
protected
members. Furthermore, even circular references are supported by binary
serialization. Note that read only properties are not serialized except the collection class objects. However, the read only properties can be serialized using binary
serialization.
If we do not require serializing a particular property of a class when using an
XmlSerializer
, we have to mark the property with the custom attribute
XmlIgnoreAttribute
. When using a
SoapFormatter
we have to use the
SoapIgnoreAttribute
instead. The
XmlSerializer
generates an in-memory assembly optimized for each type since the initial invocation to a Web Service always takes so much time. To combat this, we can use the
sgen.exe tool to pre-generate the
serialization assembly.
Conclusion
Serialization is the process of storing an object, including all of its members, to a persistent or a non-persistent storage media by converting the object into a linear stream of data. De-
serialization is the process of restoring an object's values from the said stream. The advantage of
serialization is to save the state of an object in order to have the ability to recreate the same object at a later point of time if and when it is required. The .NET Framework provides a strong support for
serialization of objects. The .NET Framework provides a unified standard for serializing and de-serializing objects for building distributed heterogeneous systems. This article has explored
Serialization and De-
serialization and the various types of
Serialization concepts with code examples wherever necessary. It has discussed what Custom
Serialization is and how to implement it. However, I would recommend not using
serialization unless it is absolutely necessary due to the drawbacks that I have already explained in this article.
There are several reasons:
Communication: If you have two machines that are running the same code, and they need to communicate, an easy way is for one machine to build an object with information that it would like to transmit, and then serialize that object to the other machine. It's not the best method for communication, but it gets the job done.
Persistence: If you want to store the state of a particular operation in a database, it can be easily serialized to a byte array, and stored in the database for later retrieval.
Deep Copy: If you need an exact replica of an Object, and don't want to go to the trouble of writing your own specialized clone() class, simply serializing the object to a byte array, and then de-serializing it to another object achieves this goal.
Caching: Really just an application of the above, but sometimes an object takes 10 minutes to build, but would only take 10 seconds to de-serialize. So, rather than hold onto the giant object in memory, just cache it out to a file via serialization, and read it in later when it's needed.
Cross JVM Synchronization: Serialization works across different JVMs that may be running on different architectures.
Serialization has a number of advantages. It provides:
- a method of persisting objects which is more convenient than writing their properties to a text file on disk, and re-assembling them by reading this back in.
- a method of issuing remote procedure calls, e.g., as in SOAP
- a method for distributing objects, especially in software componentry such as COM, CORBA, etc.
- a method for detecting changes in time-varying data.
No comments:
Post a Comment