Mark Wilson I am the creator of TopXML. I am available for international and local (Australia) contracts. I am a Solution Architect/Business Analyst. I have worked in IT in several countries (NZ, Australia, South Africa, UK) building and training teams for government and very large non-governmental organizations. I am ex-Microsoft Consulting Services. I wrote the first book on Microsoft XML published in 2000 called XML Programming with VB and ASP. Most recently I have been building tools for the SEO industry. Ask me for a 37 point SEO health-checkup for your website.
While excluding individual fields helps us getting around some
problems, there will be cases where we cannot exclude non-serializable fields
from the output because they store vital information. For these (and some
other) cases the serialization framework provides another option to customize
object serialization: Classes can take control of the data they want to
serialize by implementing the ISerializable interface.
This option requires writing actual code to handle serialization and
deserialization instead of changing the behavior simply by attaching attributes
to a class. In turn it gives us a great deal of flexibility in the way we can
save and restore objects.
After a serialization formatter checked the object it is about to
serialize for the SerializableAttribute it always queries for the ISerializable
interface to find out whether or not the object can take over its own
serialization. If the object implements this interface, the formatter calls the
interface’s only method: GetObjectData() to pass a SerializationInfo container
that the object can fill with the data it wants to serialize.
1.6
Table 12.1 The
ISerializable interface defines one single method: GetObjectData(). The
formatter calls this method to retrieve the data to serialize. Implementing
ISerializable implies implementing a deserialization constructor with the same
signature as GetObejectData.
Method
Description
void GetObjectData(
SerializationInfo info, StreamingContext context
)
Fills the
SerializationInfo info with the data to serialize. The
StreamingContext contains information to tune the serialized data to the
intended deserialization scenario.
A SerializationInfo object stores
name-value pairs, similar to a dictionary. Additionally, it provides some
properties (table 12.4) to control the type and assembly information written to
the output stream. This information will be used later on to locate the correct
type and its assembly when the object is deserialized. By default these
properties are initialized to the full type name and the fully qualified
assembly name, but we can change and cause deserialization to happen with an
instance of a different class. Changing these properties is useful if the
serialized object is only a proxy object, because it can serialize itself as if
it was the actual object.
We can store any object in the
SerializationInfo container by calling one of the many overloaded versions of
the AddValue() method. Ideally, we fill the container with enough information
to re-create the serialized object later, but there is nothing in the framework
to enforce this. Note that the SerializationInfo object will serialize objects
passed to AddValue() method the same way any other objects are serialized, i.e.
they also require the SerializableAttribute and can handle their own
serialization by implementing the ISerializable interface. The SerializationInfo
is just a data container; it has no influence to what format the data inside is
persisted to. The format is solely determined by the serialization formatter.
The BinaryFormatter produces a binary format and the SoapFormatter produces
SOAP messages with the data stored in the SerializationInfo. Once
GetObjectData() returns the formatter iterates over the items in the
SerializationInfo object and serializes the value of each name-value pair into
an element named according to the pair’s name.
1.7
Table 12.4 The properties
of the SerializationInfo class identify the serialized type and its assembly.
Property
Access
Type
Description
AssemblyName
(read/write)
string
The assembly name
of the type being (de-)serialized
FullTypeName
(read/write)
string
The full name, i.e.
class name and namespaces, of the type being (de-)serialized.