Deep Serialization: Binary and SOAP Serialization with a Generic Twist
by Joe Finsterwald
This code sample applies to ASP.NET in the .NET 2.0 framework. Examples are written in C#. 
Contents
- The Problem
- The Solution
- Step 1: Binary Serialization to a Byte Array
- Step 2: Binary Serialization to a File
- Step 3: SOAP Serialization to a String
- Step 4: Putting it all together
- Conclusion
The Problem:
You have one of the following problems:
- You need to persist an object to a storage medium.
- You are using RPC.
- You need to stream to a socket.
The solution:
Serialization allows you to convert a graph of objects into a linear sequence of bytes, XML, or SOAP.
Once an object is flattened you can store it or send it over the wire. Serialized data can then be deserialized.
Deserialization essentially reconstitutes the graph of objects you initially serialized. Serialization sounds
complicated, but in practice it’s pretty easy because the .NET framework takes care of most of the complexity for you.
Microsoft's .NET framework provides two different options for persisting data or sending it
over the network: shallow and deep serialization. Shallow serialization allows for the serialization of read-write
property values of an object. Private data members and objects referenced by the object being serialized are
ignored. Shallow serialization is used by Web Services and the XmlSerializer.
As you may have guessed from the title of this article the focus of this code sample is on deep serialization.
Deep serialization serializes the whole object and any objects referenced by the object being serialized. This code
sample demonstrates how to serialize data using the BinaryFormatter
and the SoapFormatter.
Both of these classes perform deep serialization.
In order to be eligible for serialization an object must be decorated with the [Serializable] attribute
or implement the ISerializable interface. In the event that performance is an issue you can opt to
exclude a field in an object from serialization by decorating the field with
the [NonSerialized] attribute—this is called selective serialization.
I've written the following code samples to demonstrate how easy it is to implement serialization in your project.
Step 1: Binary Serialization to a Byte Array
Binary serialization uses the BinaryFormatter which is contained in the System.Runtime.Serialization.Formatters.Binary namespace. The BinaryFormatter classes implement the IRemotingFormatter interface to support remote procedure calls (RPCs), and the IFormatter interface (inherited by the IRemotingFormatter) to support serialization of a graph of objects.
Step 2: Binary Serialization to a File
An example of binary serialization to a file.
Step 3: SOAP Serialization to a String
SOAP serialization uses the SoapFormatter which is contained in the System.Runtime.Serialization.Formatters.Soap namespace. SOAP Serialization is more versatile than binary serialization, but versatility comes at a significant cost in terms of performance.
Step 4: Putting it all together
I've put it altogether in one place if you want to include this code in a class library.
Conclusion:
Having an understanding of how serialization works is critically important if you want to be effective as a developer.
Hopefully this example has demonstrated that deep serialization is both easy to implement and powerful.