XmlSerializer Class

XmlSerializer makes possible serializing and deserializing objects 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.

Definition

Namespace: KGySoft.Serialization.Xml
Assembly: KGySoft.CoreLibraries (in KGySoft.CoreLibraries.dll) Version: 9.0.0-preview.1
C#
public static class XmlSerializer
Inheritance
Object    XmlSerializer

Remarks

  Security Note

The XmlSerializer supports polymorphism and stores type information whenever the type of a member or collection element differs from the type of the member or collection element type. If the XML content to deserialize is from an untrusted source (eg. remote service, file or database) make sure to use the DeserializeSafe or DeserializeContentSafe methods to prevent resolving any type names during the deserialization. They require to specify every natively not supported type that can occur in the serialized data whose names then will be mapped to the specified expected types.

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

  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 and the type has no parameterless constructor, then the returned instance is tried to be re-used on deserialization.

  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 None option and the default options parameter value of the serialization methods 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.

  Caution

Enabling the RecursiveSerializationAsFallback option does not guarantee that the deserialized instances will be the same as the original ones. The XmlSerializer can only instantiate objects by using their default constructor and is able to set the public fields and properties. It can also create collections by special initializer constructors and can populate them by the standard interface implementations.

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 methods using the BinarySerializationAsFallback option, then the whole XML result will be a single node with the binary content. The binary serialization is performed by the BinarySerializationFormatter class. In safe mode deserialization the specified expected types must include the types present in the embedded binary stream(s) by name.

  Note

To use binary serialization only for some types or properties you can specify the BinaryTypeConverter by the TypeConverterAttribute for a property, field or type but please note that it will always perform a safe deserialization specifying only the type of the element as expected type so you cannot use it if the corresponding type uses nested custom types that are not supported by the BinarySerializationFormatter natively. You can use also the RegisterTypeConverter extension method to specify a type converter for types.

See the XmlSerializationOptions enumeration for further options.

Natively supported types

The names of natively supported types are recognized during deserialization so they are not needed to be declared as expected custom types in safe mode.

When serializing, a wider range of types are supported without specifying any fallback options than the specified lists below. For the specific conditions see the description of the None option.

When deserializing in safe mode, refer to the following couple of lists to see which types are recognized without specifying them as expected custom types.

Natively supported simple types:

Natively supported collections:

  Note

Please note that if a collection uses a custom or culture-aware comparer, some fallback option might be needed to be able to serialize it. RecursiveSerializationAsFallback will omit the custom comparers so it is not guaranteed that such a collection can be deserialized perfectly, whereas BinarySerializationAsFallback may successfully serialize also the comparer but for safe mode deserialization it may be needed to specify also the comparer as an expected custom type.

Comparison with System.Xml.Serialization.XmlSerializer

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 cannot be serialized either. 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 is able to use the returned value of the members. If they are not after creating their container object, then the returned instances can be reused instead of creating a new instance.

Example

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>

Methods

Deserialize(Stream) Deserializes an object from the provided Stream in the stream parameter.
Deserialize(String) Deserializes an object from the specified file passed in the fileName parameter.
Deserialize(TextReader) Deserializes an object using the provided TextReader in the reader parameter.
Deserialize(XElement) Deserializes an XML content to an object. Works for the results of the Serialize(Object, XmlSerializationOptions) method.
Deserialize(XmlReader) Deserializes an object using the provided XmlReader in the reader parameter.
DeserializeContent(XElement, Object) Restores the inner state of an already created object passed in the obj parameter based on a saved XML. Works for the results of the SerializeContent(XElement, Object, XmlSerializationOptions) method.
DeserializeContent(XmlReader, Object) Restores the inner state of an already created object passed in the obj parameter based on a saved XML. Works for the results of the SerializeContent(XmlWriter, Object, XmlSerializationOptions) method.
DeserializeContentSafe(XElement, Object) Restores the inner state of an already created object passed in the obj parameter based on a saved XML. If content contains names of natively not supported types, then you should use the other overloads to specify the expected types.
See the Remarks section of the DeserializeContentSafe(XElement, Object, Type) overload for details.
DeserializeContentSafe(XmlReader, Object) Restores the inner state of an already created object passed in the obj parameter based on a saved XML. If the serialization stream contains names of natively not supported types, then you should use the other overloads to specify the expected types.
See the Remarks section of the DeserializeContentSafe(XmlReader, Object, Type) overload for details.
DeserializeContentSafe(XElement, Object, IEnumerableType) Restores the inner state of an already created object passed in the obj parameter based on a saved XML.
See the Remarks section of the DeserializeContentSafe(XElement, Object, Type) overload for details.
DeserializeContentSafe(XElement, Object, Type) Restores the inner state of an already created object passed in the obj parameter based on a saved XML.
DeserializeContentSafe(XmlReader, Object, IEnumerableType) Restores the inner state of an already created object passed in the obj parameter based on a saved XML.
DeserializeContentSafe(XmlReader, Object, Type) Restores the inner state of an already created object passed in the obj parameter based on a saved XML.
DeserializeSafe(Stream) Deserializes an object in safe mode using the specified stream. If the serialization stream contains names of natively not supported types, then you should use the other overloads to specify the expected types.
See the Remarks section of the DeserializeSafeT(XmlReader, Type) overload for details.
DeserializeSafe(String) Deserializes an object in safe mode from the specified file passed in the fileName parameter. If the file contains names of natively not supported types, then you should use the other overloads to specify the expected types.
See the Remarks section of the DeserializeSafeT(XmlReader, Type) overload for details.
DeserializeSafe(TextReader) Deserializes an object in safe mode using the provided TextReader in the reader parameter. If the serialization stream contains names of natively not supported types, then you should use the other overloads to specify the expected types.
See the Remarks section of the DeserializeSafeT(XmlReader, Type) overload for details.
DeserializeSafe(XElement) Deserializes an XML content to an object in safe mode. If content contains names of natively not supported types, then you should use the other overloads to specify the expected types.
See the Remarks section of the DeserializeSafeT(XElement, Type) overload for details.
DeserializeSafe(XmlReader) Deserializes an object in safe mode using the provided XmlReader in the reader parameter. If the serialization stream contains names of natively not supported types, then you should use the other overloads to specify the expected types.
See the Remarks section of the DeserializeSafeT(XmlReader, Type) overload for details.
DeserializeSafe(Stream, IEnumerableType) Deserializes an object in safe mode using the specified stream.
See the Remarks section of the DeserializeSafeT(XmlReader, Type) overload for details.
DeserializeSafe(Stream, Type) Deserializes an object in safe mode using the specified stream.
See the Remarks section of the DeserializeSafeT(XmlReader, Type) overload for details.
DeserializeSafe(String, IEnumerableType) Deserializes an object in safe mode from the specified file passed in the fileName parameter.
See the Remarks section of the DeserializeSafeT(XmlReader, Type) overload for details.
DeserializeSafe(String, Type) Deserializes an object in safe mode from the specified file passed in the fileName parameter.
See the Remarks section of the DeserializeSafeT(XmlReader, Type) overload for details.
DeserializeSafe(TextReader, IEnumerableType) Deserializes an object in safe mode using the provided TextReader in the reader parameter.
See the Remarks section of the DeserializeSafeT(XmlReader, Type) overload for details.
DeserializeSafe(TextReader, Type) Deserializes an object in safe mode using the provided TextReader in the reader parameter.
See the Remarks section of the DeserializeSafeT(XmlReader, Type) overload for details.
DeserializeSafe(XElement, IEnumerableType) Deserializes an XML content to an object in safe mode.
See the Remarks section of the DeserializeSafeT(XElement, Type) overload for details.
DeserializeSafe(XElement, Type) Deserializes an XML content to an object in safe mode.
See the Remarks section of the DeserializeSafeT(XElement, Type) overload for details.
DeserializeSafe(XmlReader, IEnumerableType) Deserializes an object in safe mode using the provided XmlReader in the reader parameter.
See the Remarks section of the DeserializeSafeT(XmlReader, Type) overload for details.
DeserializeSafe(XmlReader, Type) Deserializes an object in safe mode using the provided XmlReader in the reader parameter.
See the Remarks section of the DeserializeSafeT(XmlReader, Type) overload for details.
DeserializeSafeT(Stream, IEnumerableType) Deserializes an instance of T in safe mode using the specified stream.
See the Remarks section of the DeserializeSafeT(XmlReader, Type) overload for details.
DeserializeSafeT(Stream, Type) Deserializes an instance of T in safe mode using the specified stream.
See the Remarks section of the DeserializeSafeT(XmlReader, Type) overload for details.
DeserializeSafeT(String, IEnumerableType) Deserializes an instance of T in safe mode from the specified file passed in the fileName parameter.
See the Remarks section of the DeserializeSafeT(XmlReader, Type) overload for details.
DeserializeSafeT(String, Type) Deserializes an instance of T in safe mode from the specified file passed in the fileName parameter.
See the Remarks section of the DeserializeSafeT(XmlReader, Type) overload for details.
DeserializeSafeT(TextReader, IEnumerableType) Deserializes an instance of T in safe mode using the provided TextReader in the reader parameter.
See the Remarks section of the DeserializeSafeT(XmlReader, Type) overload for details.
DeserializeSafeT(TextReader, Type) Deserializes an instance of T in safe mode using the provided TextReader in the reader parameter.
See the Remarks section of the DeserializeSafeT(XmlReader, Type) overload for details.
DeserializeSafeT(XElement, IEnumerableType) Deserializes an XML content to an instance of T in safe mode.
See the Remarks section of the DeserializeSafeT(XElement, Type) overload for details.
DeserializeSafeT(XElement, Type) Deserializes an XML content to an instance of T in safe mode.
DeserializeSafeT(XmlReader, IEnumerableType) Deserializes an instance of T in safe mode using the provided XmlReader in the reader parameter.
See the Remarks section of the DeserializeSafeT(XmlReader, Type) overload for details.
DeserializeSafeT(XmlReader, Type) Deserializes an instance of T in safe mode using the provided XmlReader in the reader parameter.
Serialize(Object, XmlSerializationOptions) Serializes the object passed in obj parameter into a new XElement object.
Serialize(Stream, Object, XmlSerializationOptions) Serializes the object passed in obj into the provided Stream.
Serialize(String, Object, XmlSerializationOptions) Serializes the object passed in obj into the specified fileName.
Serialize(TextWriter, Object, XmlSerializationOptions) Serializes the object passed in obj by the provided TextWriter object.
Serialize(XmlWriter, Object, XmlSerializationOptions) Serializes the object passed in obj by the provided XmlWriter object.
SerializeContent(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.
SerializeContent(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.

See Also