KGy SOFT

XmlSerializer Class

KGy SOFT Core Libraries Help
XmlSerializer makes possible serializing and deserializing object instances into/from XML content. The class contains various overloads to support serializing directly into file or by XElement, XmlWriter, any TextWriter and any Stream implementations.
See the Remarks section for the differences compared to System.Xml.Serialization.XmlSerializer class.
Inheritance Hierarchy

SystemObject
  KGySoft.Serialization.XmlXmlSerializer

Namespace:  KGySoft.Serialization.Xml
Assembly:  KGySoft.CoreLibraries (in KGySoft.CoreLibraries.dll) Version: 5.0.0
Syntax

public static class XmlSerializer
Methods

  NameDescription
Public methodStatic memberDeserialize(Stream)
Deserializes an object from the provided Stream in stream parameter.
Public methodStatic memberDeserialize(TextReader)
Deserializes an object using the provided TextReader in reader parameter.
Public methodStatic memberDeserialize(String)
Deserializes an object from the specified file passed in fileName parameter.
Public methodStatic memberDeserialize(XElement)
Deserializes an XML content to an object. Works for results of Serialize(Object, XmlSerializationOptions) method.
Public methodStatic memberDeserialize(XmlReader)
Deserializes an object using the provided XmlReader in reader parameter.
Public methodStatic memberDeserializeContent(XElement, Object)
Restores inner state of an already created object passed in obj parameter based on a saved XML. Works for results of SerializeContent(XElement, Object, XmlSerializationOptions) and other SerializeContent overloads.
Public methodStatic memberDeserializeContent(XmlReader, Object)
Restores inner state of an already created object passed in obj parameter based on a saved XML. Works for results of SerializeContent(XmlWriter, Object, XmlSerializationOptions) and other SerializeContent overloads.
Public methodStatic memberSerialize(Object, XmlSerializationOptions)
Serializes the object passed in obj parameter into a new XElement object.
Public methodStatic memberSerialize(Stream, Object, XmlSerializationOptions)
Serializes the object passed in obj into the provided Stream.
Public methodStatic memberSerialize(TextWriter, Object, XmlSerializationOptions)
Serializes the object passed in obj by the provided TextWriter object.
Public methodStatic memberSerialize(String, Object, XmlSerializationOptions)
Serializes the object passed in obj into the specified fileName.
Public methodStatic memberSerialize(XmlWriter, Object, XmlSerializationOptions)
Serializes the object passed in obj by the provided XmlWriter object.
Public methodStatic memberSerializeContent(XElement, Object, XmlSerializationOptions)
Saves public properties or collection elements of an object given in obj parameter into an already existing XElement object given in parent parameter with provided options.
Public methodStatic memberSerializeContent(XmlWriter, Object, XmlSerializationOptions)
Saves public properties or collection elements of an object given in obj parameter by an already opened XmlWriter object given in writer parameter with provided options.
Top
Remarks

XmlSerializer supports serialization of any simple types and complex objects with their public properties and fields as well as several collection types.

Note Note
Unlike the System.Xml.Serialization.XmlSerializer class, this XmlSerializer is not designed for customizing output format (though IXmlSerializable implementations are considered). Not even Xml...Attributes are supported (except XmlRootAttribute for the root element of IXmlSerializable implementations). Instead, this class is designed to support XML serialization of any type as long as they have a default constructor and their state can be fully restored by their public fields and properties.

Several System.ComponentModel techniques are supported, which also makes possible to use the XmlSerializer for types that can be edited in a property grid, such as components, configurations or any types in a custom designer. The supported component model attributes and techniques:

Basically types with default constructors are supported. However, if a field or property value is not  after creating its parent object, then the returned instance is tried to be re-used on deserialization.

Note Note
Objects without a default constructor can be serialized at root level also by the SerializeContent methods into an already existing XElement node or by an XmlWriter, which already opened and XML element before calling the SerializeContent method. When deserializing, the result object should be created by the caller, and the content can be deserialized by the DeserializeContent methods.

Options:
By specifying the XmlSerializationOptions argument in the Serialize and SerializeContent methods you can override the default behavior of serialization. The default options and the None option ensure that only those types are serialized, which are guaranteed to be able to deserialized perfectly. For details see the description of the None option.

If a type cannot be serialized with the currently used options a SerializationException will be thrown.

You can use RecursiveSerializationAsFallback option to enable recursive serialization of every type of objects and collections. A collection type can be serialized if it implements the ICollectionT, IList or IDictionary interfaces, and it can be deserialized if it has a default constructor, or an initializer constructor with a single parameter that can accept an Array or ListT instance (non-dictionaries) or a DictionaryTKey, TValue instance (dictionary collections). Non-collection types must have a parameterless constructor to be able to be deserialized.

Note Note
If a field or property returns a non- value on deserialization, then its value is tried to be used so in this case it can be created by its container object using any custom constructor.
Caution note Caution
Enabling the RecursiveSerializationAsFallback option does not guarantee that the deserialized instances will be the same as the original ones.

If BinarySerializationAsFallback option is enabled, then types without a native support and appropriate TypeConverter will be serialized into a binary stream, which will be stored in the result XML. Though this provides the best compatibility of any type, it hides the whole inner structure of the serialized object. If a root level object without native support is serialized by the Serialize using the BinarySerializationAsFallback, then the whole XML result will be a single node with the binary content.

Note Note
To use binary serialization only for some types or properties you can specify the BinaryTypeConverter by the TypeConverterAttribute for a property or type (or you can use the RegisterTypeConverter extension method for types).

See the XmlSerializationOptions enumeration for further options.

New features and improvements compared to System.Xml.Serialization.XmlSerializer:

  • Strings - If a string contains only white spaces, then system XmlSerializer cannot deserialize it properly. String instances containing invalid UTF-16 code points are also cannot be serialized. This XmlSerializer implementation handles them correctly.
  • Collections with base element type - If the element type of a collection is a base type or an interface, then the system serializer throws an exception for derived element types suggesting that XmlIncludeAttribute should be defined for all possible derived types. Unfortunately this attribute is applicable only for possible types of properties/fields but not for collection elements. And in many cases it simply cannot be predefined in advance what derived types will be used at run-time.
  • Collections with read-only properties - Usually collection properties can be read-only. But to be able to use the system serializer we need to define a setter for such properties; otherwise, serialization may fail. This XmlSerializer does not require setter accessor for a collection property if the property is not  after initialization and can be populated by using the usual collection interfaces.
  • Objects without default constructors - The system serializer requires that the deserialized types have default constructors. On deserializing fields and properties, this XmlSerializer implementation tries to use the return value of the members. If they are not  after creating their container object, then the returned instances will be used instead of creating a new instance.

Examples

Tip Tip
Try also online.
C#
using System;
using System.IO;
using System.Text;
using System.ComponentModel;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Xml.Linq;
using KGySoft.CoreLibraries;
using KGySoft.Serialization.Xml;

// A good candidate for XML serialization:
public class Person
{
    public string FirstName { get; set; }

    [DefaultValue(null)] // will not be serialized if null
    public string MiddleName { get; set; }

    public string LastName { get; set; }

    public DateTime BirthDate { get; set; }

    // System serializer fails here: the property has no setter and its type cannot be instantiated.
    public IList<string> PhoneNumbers { get; } = new Collection<string>();
}

public class Program
{
    public static void Main()
    {
        var person = ThreadSafeRandom.Instance.NextObject<Person>();
        var options = XmlSerializationOptions.RecursiveSerializationAsFallback;

        // serializing into XElement
        XElement element = XmlSerializer.Serialize(person, options);
        var clone = (Person)XmlSerializer.Deserialize(element);

        // serializing into file/Stream/TextWriter/XmlWriter are also supported: An XmlWriter will be used
        var sb = new StringBuilder();
        XmlSerializer.Serialize(new StringWriter(sb), person, options);
        clone = (Person)XmlSerializer.Deserialize(new StringReader(sb.ToString()));

        Console.WriteLine(sb);
    }
}

// This code example produces a similar output to this one:
// <?xml version="1.0" encoding="utf-16"?>
// <object type="Person">
//   <FirstName>Uehaccuj</FirstName>
//   <MiddleName>Rnig</MiddleName>
//   <LastName>Iuvmozu</LastName>
//   <BirthDate>1996-06-02T00:00:00Z</BirthDate>
//   <PhoneNumbers type="System.Collections.ObjectModel.Collection`1[System.String]">
//     <item>694677853</item>
//     <item>6344</item>
//   </PhoneNumbers>
// </object>
See Also

Reference