Need to dump an object? Serialize it into XML.

I recently found myself wanting to dump an object into a human readable text format for debugging purposes. I first looked into Microsoft’s ObjectDumper class included in the samples folder of Visual Studio 2008.

It works okay but by default it outputs to the console and isn’t formatted very well. I spent about half an hour modifying it to my liking but I still couldn’t get it looking right and just wanted something easier to work with.


So then I thought about what I really desired:

  • Easily readable
  • Ability to save to a text file, database, or email it
  • And possibly import it back into the application to populate the object
After thinking about that, the solution came easy. I’d just serialize the object to XML. So I wrote a helper class to do just that and used Generics to make the helper methods short and sweet.

And just to expand upon why one might use this or find it useful, here is one example:

  • Your error logs for your website/application look strange and you’re not quite sure what is happening or what the user is doing to cause a crash. Wouldn’t it be nice to be able to dump the model(s) to your error log as well to ensure that they are not getting into some weird state or being populated with data that they shouldn’t be?

Below you’ll find a working example of a console app with comments. If you find it useful, feel free to use the code however you wish and/or leave a comment.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace XmlSerializationExample
{
    class Program
    {
        static void Main(string[] args)
        {
            // Instantiate a new Customer and his two addresses
            var customer = new Customer()
            {
                FirstName = "Jim",
                LastName = "Bean",
                Addresses = new List<Address>
                {
                    new Address()
                    {
                        StreetName1 = "890 Tailtell St.",
                        City = "Nelman",
                        State = "TX",
                        Zip = "72846-8469"
                    },
                    new Address()
                    {
                        StreetName1 = "120 Sandall Dr.",
                        City = "Nelman",
                        State = "TX",
                        Zip = "72846-8470"
                    }
                }
            };

            // Convert the Customer object to Xml
            string xml = XmlSerializers.ObjectToXml(customer);

            // Output the Xml to make sure it's working
            Console.WriteLine(xml);

            // Convert the Xml back into a new Customer object
            var customer2 = (Customer)XmlSerializers.XmlToObject(xml, new Customer());

            // Convert the new Customer object to Xml
            string xml2 = XmlSerializers.ObjectToXml(customer2);

            // Output the Xml to make sure it's working
            Console.WriteLine(xml2);

            Console.ReadLine();
        }
    }

    public static class XmlSerializers
    {
        /// <summary>
        /// Serialize an object to Xml
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj">An object of any type</param>
        /// <returns>Xml representation of the given object</returns>
        public static string ObjectToXml<T>(T obj)
        {
            System.IO.StringWriter sw = new System.IO.StringWriter();

            System.Xml.Serialization.XmlSerializer serializer =
                new System.Xml.Serialization.XmlSerializer(typeof(T));

            serializer.Serialize(sw, obj);

            return sw.ToString();
        }

        /// <summary>
        /// Deserialize Xml to an object
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="xml">A string containing well-formed Xml</param>
        /// <param name="obj">An object of any type</param>
        /// <returns>Object of a given type</returns>
        public static object XmlToObject<T>(string xml, T obj)
        {
            System.IO.StringReader sr = new System.IO.StringReader(xml);

            System.Xml.Serialization.XmlSerializer serializer =
                new System.Xml.Serialization.XmlSerializer(typeof(T));

            return (T)serializer.Deserialize(sr);
        }
    }

    public class Customer
    {
        // A Customer can have many addresses
        private List<Address> _addresses = new List<Address>();

        public string FirstName { get; set; }
        public string LastName { get; set; }
        public List<Address> Addresses
        {
            get { return _addresses; }
            set { _addresses = value; }
        }
    }

    public class Address
    {
        public string StreetName1 { get; set; }
        public string StreetName2 { get; set; }
        public string StreetName3 { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string Zip { get; set; }
    }
}

Update [11/15/2011]:
Well, I never ran into this use case with XML serialization before but it seems that it cannot handle serializing IList<T>.
To solve this you can simply cast your IList<T> to a List<T> before serialization.