Skip to main content

Extension for simplify usage of XmlSerializer class. Add extension to any object serialize it to xml. Add extension to string and stream to deserialize objects. All extensions with first check about default constructor.

/// <summary>
/// Extensions for supporting xml serialization by <see cref = "XmlSerializer" />.
/// </summary>
public static class XmlSerializerExtensions
{
    private static readonly Dictionary<RuntimeTypeHandle, XmlSerializer> ms_serializers = new Dictionary<RuntimeTypeHandle, XmlSerializer>();

    /// <summary>
    /// Serialize object to xml string by <see cref = "XmlSerializer" />
    /// </summary>
    /// <typeparam name = "T"></typeparam>
    /// <param name = "value"></param>
    /// <returns></returns>
    public static string ToXml<T>(this T value) where T : new()
    {
        var _serializer = GetValue(typeof (T));
        using (var _stream = new MemoryStream())
        {
            using (var _writer = new XmlTextWriter(_stream, new UTF8Encoding()))
            {
                _serializer.Serialize(_writer, value);
                return Encoding.UTF8.GetString(_stream.ToArray());
            }
        }
    }

    /// <summary>
    /// Serialize object to stream by <see cref = "XmlSerializer" />
    /// </summary>
    /// <typeparam name = "T"></typeparam>
    /// <param name = "value"></param>
    /// <param name = "stream"></param>
    public static void ToXml<T>(this T value, Stream stream) where T : new()
    {
        var _serializer = GetValue(typeof (T));
        _serializer.Serialize(stream, value);
    }

    /// <summary>
    /// Deserialize object from string
    /// </summary>
    /// <typeparam name = "T">Type of deserialized object</typeparam>
    /// <param name = "srcString">Xml source</param>
    /// <returns></returns>
    public static T FromXml<T>(this string srcString) where T : new()
    {
        var _serializer = GetValue(typeof (T));
        using (var _stringReader = new StringReader(srcString))
        {
            using (XmlReader _reader = new XmlTextReader(_stringReader))
            {
                return (T) _serializer.Deserialize(_reader);
            }
        }
    }

    /// <summary>
    ///   Deserialize object from stream
    /// </summary>
    /// <typeparam name = "T">Type of deserialized object</typeparam>
    /// <param name = "source">Xml source</param>
    /// <returns></returns>
    public static T FromXml<T>(this Stream source) where T : new()
    {
        var _serializer = GetValue(typeof (T));

        return (T) _serializer.Deserialize(source);
    }

    private static XmlSerializer GetValue(Type type)
    {
        XmlSerializer _serializer;
        if (!ms_serializers.TryGetValue(type.TypeHandle, out _serializer))
        {
            lock (ms_serializers)
            {
                if (!ms_serializers.TryGetValue(type.TypeHandle, out _serializer))
                {
                    _serializer = new XmlSerializer(type);
                    ms_serializers.Add(type.TypeHandle, _serializer);
                }
            }
        }

        return _serializer;
    }

}

// -----------------------------------------------------
// Example
// -----------------------------------------------------

List<string> list = new List<string>{"aaa","bbb","ccc"};
List<string> listActual = null;

// Xml serialize to string
string xml = list.ToXml();

// Deserialize from string
listActual = xml.FromXml<List<string>>();

using(var stream = new MemoryStream())
{
    // Serialize to stream
    list.ToXml(stream);

    stream.Position = 0;
    // Deserialize
    listActual = stream.FromXml<List<string>>();
}