Was this helpful?
This article is in continuation to this post Serialization in .NET Part 2
In addition to the Binary and SOAP formatters, the .NET provides another type of formatter called XmlSerializer. This resides in the System.Xml.Serialization namespace. Working with this type is a little different from working with the Binary and SOAP formatters.
You can use this formatter to serialize the state of a given object in pure XML format. This is in contrast to XML data wrapped within a SOAP message. Since the SOAP-protocol specifics are not included, the XML stream produced is more compact which makes it ideal for transmission and storage. It enables an application to interoperate with other systems and exchange data in XML format. It is used by ASP.NET to generate XML Web service messages.
XmlSerializer does not pay any attention to the Serializable attribute. The class itself offers similar functionality to a certain extent. The serialization process is built into the XmlSerializer.
Restrictions apply to XML Serialization
By default, the locally-installed applications don't have any security restrictions in that they can access the private fields. However, certain security restrictions apply to applications running from the network. XmlSerializer is designed to run in such environments that have limited permissions. Therefore, XmlSerializer has to restrict itself to use the shallow serialization technique. It can serialize only the public members that can be accessed even without any special permission settings.
Several restrictions have been imposed on the classes that the XmlSerializer can process. It will only then be able to successfully deserialize the objects of applications that are running with limited security permissions. The types of restrictions are as follows:
a. Before the XmlSerialer.Deserialize() method initializes all the fields of a class, it should be able to create an instance of the class in insecure environments. However, creating the instance without making a call to the default constructor is possible only if you grant certain permissions to the executing application. Therefore, you must provide a default constructor for the class that you want XmlSerializer to serialize.
b. The class must be declared public. Processing the internal and private classes is only possible if you provide certain permissions to the application.
c. Only public read-write properties and public fields are serialized. The read-only and write-only properties are ignored.
d. The code inside property accessors should not require any security privileges.
Certain other limitations exist on the types that XmlSerializer can serialize and deserialize:
a. You cannot use multi-dimensional arrays because they cannot be mapped to XML. In its place, use nested arrays.
b. An object that is referenced more than one time is serialized each time it is referenced. It is because of the fact that XmlSerializer does not have the ability to preserve the object's identity.
c. A type should not implement IDictionary interface. For example, XmlSerializer is not able to operate on collections like Hashtable, SortedList.
d. You cannot serialize an object graph that contains circular references for e.g. doubly-linked lists.
XmlSerializer is able to operate on certain .NET types, like Arrays, ArrayList, DateTime, DataSet. These types meet the requirements listed above.
No restrictions apply to SOAP Formatter
Unlike XmlSerializer, SoapFormatter does not place any such restrictions.
a. Providing a default constructor for a serialized class is not mandatory.
b. The class does not need to be declared as public.
c. SOAPFormatter can serialize both public and private properties and fields.
d. It can properly resolve circular references, for instance, the doubly-linked lists can be serialized.
e. Dictionaries can be serialized.
f. An object that is referenced multiple times is serialized exactly once. The SOAPFormatter provides a serial number to an object that gets serialized and keeps track of the duplicate objects. When serializing an object, the formatter determines if the same object has already been stored. If not, it serializes the object's data and gives it a serial number. If yes, it simply writes "this object is previously serialized having serial number N".
XML Serialization metadata attributes
XmlSerializer provides certain special serialization metadata attributes. They reside in the System.Xml.Serialization namespace. They override the XmlSerializer's default formatting. They control how objects are mapped to arbitrary XML formats. We'll discuss some of them.
Internal Working of XMLSerializer
XmlSerializer offers several constructors providing alternatives to customize the serialization at runtime. For instance, you can control the serialization of objects contained in a DLL even if you don't have access to the DLLs source code.
This is how a constructor works internally. It uses the reflection technique to examine the public fields and properties of a type. It extracts the type information and stores it in a cache. The type information includes the data types of public properties and fields and the serialization metadata attributes. It also maps each field/property to XML. By default, it maps the field/property to an XML element with the same name. However, if it encounters the XmlElement and XmlAttribute attributes attached to the fields, the mapping is modified accordingly.
The constructor then processes the type information to generate the temporary classes. These classes are then compiled into a temporary assembly making the serialization and deserialization very fast.
Instead of doing it again and again, you should plan to construct an XmlSerializer for a particular type only once. Examining the type, taking out the information, generating the temporary classes, and compiling them into an assembly are time-consuming operations. This will help you save the performance overhead. Also, retain the XmlSerializer instance as long as your application runs.
The XmlSerializer.Serialize() method checks an object to determine its type. It then searches the cache to get the corresponding type-mapping. Finally, it serializes the object according to the format specified in the mapping.
The XmlSerializer.Deserialize() method examines the XML data to determine the types that it'll construct. It then searches the cache to get the corresponding type-mapping. Finally, it constructs the object according to the format specified in the mapping.
XML Serialization Example
Example: Explicitly declaring the types of objects you're about to serialize
You need to tell the XmlSerializer constructor beforehand about all the types that it's going to serialize. Consider serializing an object of type ArrayList. The serializer will attempt to serialize the objects stored inside the ArrayList. It is not possible for you to statically declare the types that you wish to store inside the ArrayList. It is due to the fact that you cannot hardcode the attributes inside the ArrayList class.
The above statement throws an exception because you were not able to tell the constructor that an object of type ChatRoom is stored in the rooms ArrayList.
In this case, you need to declare the types that are referenced from ArrayList. Use the overloaded constructor that accepts a
The XMLSerializer constructor cannot automatically locate the derived types at the time when it examines the structure of a type.
The XmlInclude attribute is applied to a class allowing you to declare the derived types. You must furnish this attribute for each of the derived types, XmlSerializer will only then be able to serialize the objects of the derived types.
The constructor uses the information provided in the XmlInclude attribute to determine the derived type and extract and process the type mapping for the derived type.
For Part 3, click this link: Serialization in .NET - Part 4
|posted||Apr 08, 2016|
|active||Apr 13, 2016|
|•||.NET Core project option: "Produce outputs on build"|
|•||Fastest way to serialize a POCO to JSON and deserialize JSON to a POCO|
|•||Serialization in .NET - Part 4|
|•||Reading appsettings.json in a .NET Core console application|
|•||Serialization in .NET - Part 2|
|•||Serialization in .NET - Part 1|
|•||Reading appsettings.json in a .NET Core console application|
|•||Going forward: Should I rewrite my HtmlHelpers into TagHelpers?|
|•||How do I get the response from an asynchronous Ajax call?|
|•||When to use 'ref' and 'out' keywords - specifically with strings?|