MCTS Exam 70-536 – Serialization
Its getting hot in here … so, I scheduled my exam – Wish me luck. Till then, I will try to catch-up on my writing cause I think this is a very efficient way for last minute learning – Today’s topic is serialization. Enjoy!
Common
- Serialization is implemented in the System.Runtime.Serialization-namespace
- objects can be stored or transferred and then be recreated
- Serialization High-Level steps are the following
- Create a stream object to hold the output
- Create a BinaryFormatter object (in System.Runtime.Serialization.Formatters.Binary)
- Call the BinaryFormatter.Serialize
- with BinaryFormatter, output will be stored as ASCII text
- Deserialization High-Level steps are the following
- Create a stream object to read
- Create a BinaryFormatter object (in System.Runtime.Serialization.Formatters.Binary)
- Create a new object to hold the deserialized data
- Call BinaryFormatter.Deserialize
Serializable Class
- Make a class serializable, by adding the Serializable Attribute to it
- Even if you don’t need it now, its good practice to enable it anyway
- You can disable serialization of members with the NonSerialized Attribute in front of them
- To initialize non-serialized members automatically on deserialization, implement the IDeserializationCallback interface and implement the OnDeserializationCallback-method.
- Version Compatibility can be reached by adding the OptionalField Attribute to a member added. So also previously serialized versions of the class can be deserialized properly
- Best Practice:
- Never remove a serialized member
- Never apply NonSerialized to a field that didn’t have this attribute in the previous version
- Never change the name or the type of a serialized field
- apply OptionalField to new fields (also, if you remove NonSerialized -Attribute)
- Set meaningful default values for all optional fields Using callbacks
- There are different Serialization-Formats
- BinaryFormatter – Most efficient for objects, only readable by .NET Apps
- SoapFormatter – Most reliable, if not only .NET Apps are consuming. XML based. Objects is consuming 3 or 4 times more space.
- Control Soap Serialization with the following attributes
- SoapAttribute – Class member will be serialized as XML attribute
- SoapDefaultValue – default value of member
- SoapElement – member will be serialized as XML element (node)
- SoapEnum – element name of an enumeration member
- SoapIgnore – ignore the field
- SoapType – schema for the xml that is generated
- Guidelines
- when in double, mark a class as Serializable
- mark temporary or calculated members as NonSerialized
- use SoapFormatter for portability, use BinaryFormatter for efficiency
XML Serialization
- Use it, when you need to exchange objects with non .NET applications.
- Following Benefits above standard serialization:
- Greater interoperability
- More admin-friendly – objects serialized can be viewed in notepad
- Better forward-compatibility – xml is self describing
- Use XML Serialization to be conform to an XSD
- Limitations are
- can only serialize public data
- can not serialize object graphs, only objects
- Steps to use XML Serialization
- Create stream, TextWriter or XmlWriter to hold output
- Create XmlSerializer and pass the type of the object you want to serialize
- Call XmlSerializer.Serialize to serialize the object
- Steps to use Deserialization
- Create stream, TextReader or XmlReader to read the input
- Create an XmlSerializer object by passing the type
- Call XmlSerializer.Deserialize method
- To create a class that can be serialized with XmlSerializer do the following
- Specify the class as public
- Specify all members you want to serialize as public
- Create a parameterless constructor
- How to control Xml Serialization
- Use he following Attributes to tag the members of your class
- XmlAnyAttribute – when deserializing, array will be filled with XmlAttributes unknown to the schema
- XmlAnyElement – same as XmlAnyAttribute but with elements
- XmlArray – members of the array will be generated as members of an Xml array
- XmlArrayItem – derived types can be inserted into an array – usually in conjunction with XmlArray
- XmlAttribute – Member will be serialized as Xml attribute
- XmlChoiceIdentifier – member can be disambiguated by using an array
- XmlElement – Member will be serialized as Xml Element
- XmlEnum – Element name of an enumeration member
- XmlIgnore – Similar to NonSerialized, ignore member while serializing
- XmlInclude – Include class when schema generated to recognize when serialize
- XmlRoot – Specifying namespace or element name of root
- XmlText – Serialized as Xml text
- XmlType – name and namespace of XmlType
- Example to attributes
[XmlRoot(“ShoppingItem”]
public class CartItem
{[XmlAttribute] public int userId;
- Use he following Attributes to tag the members of your class
- Complete control can be reached by implementing IXmlSerializable interface in your class, and implement ReadXml and WriteXml methods
- Avoid inflation by using Base64 encoding
- When possible, leverage an exiting Xml Schema
- Run the Xsd.exe-Tool to create classes that are strongly typed to a schema (ex. Xsd.exe schema.xsd / classes / language;[CS|VB])
- You can also serialized DataSets and Collections
Custom Serialization
- implement ISerializable interface and apply Serializable attribute to class
- Use CS, if the class has declarative or imperative security at class level or its constructor
- Implement GetObjectData and a special constructor (used for deserialization)
- Populate SerializationInfo in GetObjectData method – Add values as Key/Value pair using AddValue (Creates internal SerializationEntry structure)
- In constructor, fill members with values provided
- You can use different IFormatterConverter Implementations in SerializationInfo constructor
- Throw an SerializationException if invalid data is provided
Serialization Events
- .NET supports serialization events when using BinaryFormatter (Only for this)
- For SoapFormatter and custom serialization you are limited to use IDeserializationCallback-Interface events. they are
- Serializing – just before serializing. Apply OnSerialization-attribute to the method that should run.
- Serialized – after serializiation. Apply OnSerialized-attribute.
- Deserializing – just before deserializing. Apply OnDeserializing-attribute.
- Deserialized – after deserializing. Apply OnDeserialized-attribute. You should use OnDeserialization instead when not using BinaryFormatter.
- The sequence is the same then in the list, but OnDeserialization will fire BEFORE OnDeserialized
- Methods do not alter serialization stream, but you can modify the object.
- The methods applied to the Callback-events must meet the following criteria
- Accept StreamingContext object as a parameter
- return void
- Have the corresponding attribute (as described before)
Change Serialization based on Context
- Context may be the destination, so you probably want to serialize differently.
- StreamingContext provides information about the current context
- It has two properties
- Context – the context information (individual)
- State – indicating the source (deserialization) or destination(serialization) of the object being serialized/deserialized
- CrossProcess – different process, same machine
- CrossMachine – different machine
- File – source or destination is file
- Persistence – store such as database, file etc.
- Remoting – remoting to unknown location
- Other – unknown
- Clone – object being cloned
- CrossAppDomain – different AppDomain
- All – might be any of the above
- Make sure to set the context information in the Formatter before calling Serialize or Deserialize
Custom Formatter
- To implement a custom formatter, implement IFormatter and use the FormatterService-class’ static methods as helpers.
Further Reading
Big one, keep on learning
Sascha
Source: Microsoft.NET Framework-Application Development Foundations by Tony Northrup, 2nd Edition


