In most cases the .NET built-in serialization engine
is good enough. But if it does not meet your particular needs, you can
override the serialization process with custom serialization. Basically
this means implementing the ISerializable interface that requires the implementation of the GetObjectData
method. Such a method is important because it is invoked during
serialization. Moreover a custom implementation of the class constructor
must be provided. Basically you have to first reproduce at least what
built-in formatters do during serialization. Code in Listing 1 shows how to provide custom serialization for the Person class.
Listing 1. Providing Custom Serialization
Imports System.Runtime.Serialization Imports System.Security.Permissions
<Serializable()> Public Class Person Implements ISerializable
Public Overridable Property FirstName As String Public Overridable Property LastName As String Public Overridable Property Age As Integer
<SecurityPermission(SecurityAction.Demand, SerializationFormatter:=True)> Protected Sub GetObjectData(ByVal info As System.Runtime.Serialization. SerializationInfo, ByVal context As System.Runtime.Serialization. StreamingContext) _ Implements System.Runtime.Serialization.ISerializable. GetObjectData
info.AddValue("First name", Me.FirstName) info.AddValue("Last name", Me.LastName) info.AddValue("Age", Me.Age) End Sub
'At deserialization time Protected Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext) MyBase.New() Me.FirstName = info.GetString("First name") Me.LastName = info.GetString("Last name") Me.Age = info.GetInt32("Age") End Sub End Class
|
The GetObjectData method is basically invoked when you pass an object to the Serialize method of a formatter and require an info argument of type SerializationInfo. This class stores all information needed for serialization. It exposes an AddValue
method that stores data and a value utilized for recognizing data.
Notice that the information is retrieved by the special constructor
implementation that is invoked at deserialization time via GetXXX methods where XXX corresponds to .NET types such as Int32, Boolean, Short, and so on. Also notice how GetObjectData is decorated with the SecurityPermission
attribute demanding for permissions about the serialization formatter.
This is necessary because the permission is allowed only to full-trusted
code, thus intranet and Internet zones are not allowed. Both GetObjectData and the constructor are Protected
so that derived classes can still take advantage of them but are
prevented from being public. If you are sure that your class will not be
inherited, GetObjectData can also be Private.
When you create a class that inherits from another class where ISerializable is implemented, if you add new members, you can also provide a new implementation of both GetObjectData and the constructor.
|
Implementing ISerializable is not the only way for controlling serialization. You can control serialization events, too.
Serialization Events
The serialization process raises four events, which are summarized in Table 1.
Table 1. Serialization Events
Event | Description |
---|
OnSerializing | Occurs just before serialization begins |
OnSerialized | Occurs just after serialization completes |
OnDeserializing | Occurs just before deserialization begins |
OnDeserialized | Occurs just after deserialization completes |
Serialization events are
handled differently than classic events. There is an attribute for each
event that you can handle as follows:
'Invoke this method before
'serialization begins
<OnSerializing()>
Private Sub FirstMethod()
End Sub
'Invoke this method after
'serialization completes
<OnSerialized()>
Private Sub SecondMethod()
End Sub
'Invoke this method before
'deserialization begins
<OnDeserializing()>
Private Sub ThirdMethod()
End Sub
'Invoke this method after
'deserialization completes
<OnDeserialized()>
Private Sub FourthMethod()
End Sub
The
runtime takes care of invoking the specified method according to the
moment represented by each attribute. In this way you can provide
additional actions based on serialization events.