In .NET, serialization is the process of converting a complex object into a bit stream or XML string, which can be saved into a file or sent over a network connection. Serialization is extensively used in web services to transfer information from client to server, and for saving .NET objects into an SQL database.
In this tutorial, I will show you how to implement binary serialization in .NET; you’ll quickly find that many objects in .NET are not natively serializable, so I’ll also show you how to customize an object to manually make it serializable.
Serializable Objects
If an object is natively serializable, it is an extremely simple process to turn a complex object into a byte array. The following class can be used in just about any situation to serialize or deserialize an object:
Imports System.Runtime.Serialization.Formatters.Binary Imports System.IO Public Class Serialization Public Shared Function Serialize(ByVal Obj As Object) As Byte() Dim MS As New MemoryStream Dim BF As New BinaryFormatter BF.Serialize(MS, Obj) Return MS.ToArray End Function Public Shared Function Deserialize(ByVal SerializedData() As Byte) As Object Dim MS As New MemoryStream(SerializedData) Dim BF As New BinaryFormatter Return BF.Deserialize(MS) End Function End Class
The following example, utilizing the ‘Serialization’ class from above, will convert ‘SomeObject’ into a byte array and back into a generic object. Note that the ‘Object’ can be casted into whatever you want:
Dim SerializedData() as Byte = Serialization.Serialize(SomeObject) Dim DeserializedObject as Object = Serialization.Deserialize(SerializedData)
Once an object is converted into a byte array, you can save it into an SQL database, write it to the disk, or even Response.BinaryWrite() it out to the user.
Serialization of Unserializable Objects
There are quite a few objects in .NET (my most recent bout was with MailMessage and MailAddress) that cannot be serialized using the above method. If you need to serialize these objects, you must tell .NET how an object should be serialized. This often means that you’ll need to make a custom class that inherits an unserializable class, and then specify the class’s serialization map.
To manually specify how an object is serialized/deserialized, you need to include two functions. I learn much better with examples rather than explanation, so I’ll give you the example first:
Imports System.Runtime.Serialization <Serializable()> _ Public Class SomeClass Implements ISerializable Public SomeProperty As String Public Sub New(ByVal info as SerializationInfo, ByVal c as StreamingContext) Me.SomeProperty = info.GetValue("SomeProperty", GetType(String)) End Sub Public Sub GetObjectData(ByVal info SerializationInfo, ByVal context as StreamingContext) _ Implements ISerializable.GetObjectData info.AddValue("SomeProperty", Me.SomeProperty, GetType(String)) End Sub
Explanation
By including a New() and GetObjectData() method, .NET will know exactly how to serialize an object. Without these methods, .NET would have no way of knowing how to convert your class into a bit stream, and it would throw an error. I would like to point out a few small things of note in the above example:
- Include <Serializable()> _ before you declare your class — this tells .NET that your class is serializable. You need to include a (space)(underscore) because, unlike in C#, VB.NET pays attention to white space and it won’t associate your XML tag with the class. If you’re weirded out with the underscore, you can just put everything on the same line, like <Serializable()> Public Class SomeClass.
- Your class has to implement ISerializable — this allows you to use the GetObjectData() method later on.
- The New() method is actually handling deserialization — it’s setting the Me.SomeProperty property based on the info object that is passed as an argument.
- The GetObjectData() method must implement ISerializable.GetObjectData. This method is responsible for serialization — it will store the Me.SomeProperty variable, which is a GetType(String).
Custom Serialization
Once you’ve declared the GetType() and New() methods for your custom class, you can use the ‘Serialization’ custom class at the beginning of this document to serialize your class just as if it was normally a serializable object.