C# XML and Binary Serialization

By Kenneth 'RabidDog' Clark at November 08, 2011 17:55
Filed Under: C#, Code, Architecture

Recently was working on a small project that required me to store a collection of objects. So I figured I would refresh my knowledge of the serialization available in C#.

 

First I had a look at the XmlSerializer. First you need to define an object to serialize.

 

[Serializable, XmlRoot(Namespace = "http://rabiddog.co.za")]
public class Dog
{
    public Dog(String name, int age)
    {
        this.Name = name;
        this.Age = age;
    }

    public string Name { get; set; }
    public int Age { get; set; }

    //The XmlSerializer requires a default Constructor
    public Dog() { }
}

 

Now that we have the class defined, lets create a collection and serialize that collection to an XML file. Create a console application and then add the following method

 

private static void XmlSerialize()
{
    Dog dog1 = new Dog("Charlie", 42);
    Dog dog2 = new Dog("Jim", 32);


    List<Dog> myDogs = new List<Dog>{dog1, dog2};

    using (Stream stream = new FileStream("MyDogs.xml", FileMode.Create, FileAccess.Write, FileShare.None))
    {
        XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Dog>), new Type[]{typeof(Dog)});
        xmlSerializer.Serialize(stream, myDogs);
    }
}

 

Then call the method from the Main() function, let it run and you should end up with a file called MyDogs.xml in the debug/bin directory. The file should look something like this

<?xml version="1.0"?>
<ArrayOfDog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Dog>
    <Name xmlns="http://rabiddog.co.za">Charlie</Name>
    <Age xmlns="http://rabiddog.co.za">42</Age>
  </Dog>
  <Dog>
    <Name xmlns="http://rabiddog.co.za">Jim</Name>
    <Age xmlns="http://rabiddog.co.za">32</Age>
  </Dog>
</ArrayOfDog>
 

Well that was pretty simple. All we had to do was add the [Serializable] annotation to the class and then create an instance of XmlSerializer to write it to. You could also set the properties to be attributes by decorating them with the [XmlAttribute] annotation.

 

Cool, lets move onto the binary serialization shall we? Using the same Dog class we are going to serialize this down to a binary file.

 

We do that by changing the serializer we are using to the BinaryFormatter:

private static void BinarySerialize()
{
    Dog dog1 = new Dog("Charlie", 42);
    Dog dog2 = new Dog("Jim", 32);


    List<Dog> myDogs = new List<Dog> { dog1, dog2 };

    BinaryFormatter formatter = new BinaryFormatter();

    using (Stream stream = new FileStream("MyDogs.dat", FileMode.Create, FileAccess.Write, FileShare.None))
    {
        
        formatter.Serialize(stream, myDogs);
    }
}

 

Don’t forget to call this method from the Main method. This should produce a MyDogs.dat file in the debug/bin directory. Happy days but there is just one problem. What good is it serializing it if we can deserialize it?

 

First lets deserialize our XML like so

private static void XmlDeserialize()
{

    using (Stream stream = new FileStream("MyDogs.xml", FileMode.Open, FileAccess.Read))
    {
        XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Dog>), new Type[] { typeof(Dog) });
        List<Dog> myDogs = (List<Dog>)xmlSerializer.Deserialize(stream);

        foreach(Dog dog in myDogs)
        {
            Console.WriteLine("My Dog {0} is {1} years old", dog.Name, dog.Age);
        }
    }
}

 

And the method to deserialize our binary file would be something along the lines of

private static void BinaryDeserialize()
{
    BinaryFormatter formatter = new BinaryFormatter();
    using (Stream stream = new FileStream("MyDogs.dat", FileMode.Open, FileAccess.Read))
    {
        List<Dog> myDogs = (List<Dog>)formatter.Deserialize(stream);

        foreach (Dog dog in myDogs)
        {
            Console.WriteLine("My Dog {0} is {1} years old", dog.Name, dog.Age);
        }
    }
}

 

It thought this was a particularly neat way of storing data on application close. Serialize your object graphs and exit. When you start the application deserialize back to the original state and off you go. No over head of setting up database connections or any other mechanisms of persistence.

 

Yes I know it is old school but is facilitates the requirements for the application I am using. The reason I raise it is because we far to often get caught up in distributed application mentality when something simple like this would do just fine! Below is the enter class file. I hope some one found this useful Smile

 

using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Xml.Serialization;

namespace RabidDog
{
    class Program
    {

        private static void XmlSerialize()
        {
            Dog dog1 = new Dog("Charlie", 42);
            Dog dog2 = new Dog("Jim", 32);


            List<Dog> myDogs = new List<Dog>{dog1, dog2};

            using (Stream stream = new FileStream("MyDogs.xml", FileMode.Create, FileAccess.Write, FileShare.None))
            {
                XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Dog>), new Type[]{typeof(Dog)});
                xmlSerializer.Serialize(stream, myDogs);
            }
        }

        private static void XmlDeserialize()
        {

            using (Stream stream = new FileStream("MyDogs.xml", FileMode.Open, FileAccess.Read))
            {
                XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Dog>), new Type[] { typeof(Dog) });
                List<Dog> myDogs = (List<Dog>)xmlSerializer.Deserialize(stream);

                foreach(Dog dog in myDogs)
                {
                    Console.WriteLine("My Dog {0} is {1} years old", dog.Name, dog.Age);
                }
            }
        }


        private static void BinarySerialize()
        {
            Dog dog1 = new Dog("Charlie", 42);
            Dog dog2 = new Dog("Jim", 32);


            List<Dog> myDogs = new List<Dog> { dog1, dog2 };

            BinaryFormatter formatter = new BinaryFormatter();

            using (Stream stream = new FileStream("MyDogs.dat", FileMode.Create, FileAccess.Write, FileShare.None))
            {
                
                formatter.Serialize(stream, myDogs);
            }
        }

        private static void BinaryDeserialize()
        {
            BinaryFormatter formatter = new BinaryFormatter();
            using (Stream stream = new FileStream("MyDogs.dat", FileMode.Open, FileAccess.Read))
            {
                List<Dog> myDogs = (List<Dog>)formatter.Deserialize(stream);

                foreach (Dog dog in myDogs)
                {
                    Console.WriteLine("My Dog {0} is {1} years old", dog.Name, dog.Age);
                }
            }
        }

        static void Main(string[] args)
        {
            XmlSerialize();
            BinarySerialize();
            XmlDeserialize();
            BinaryDeserialize();
        }
    }

    [Serializable, XmlRoot(Namespace = "http://rabiddog.co.za")]
    public class Dog
    {
        public Dog(String name, int age)
        {
            this.Name = name;
            this.Age = age;
        }

        public string Name { get; set; }
        public int Age { get; set; }

        //The XmlSerializer requires a default Constructor
        public Dog() { }
    }
}

Add comment




  Country flag
biuquote
  • Comment
  • Preview
Loading








I am South African. Always have been always will be. I love my country. I love my wife and two children.


I also really enjoy solving problems. I currently work as a Software Architect exploring new solutions for business problems. Having been round the block a few times I enjoy showing new developers how best to solve problems, how to find answers and how to approach solution development.


In my spare time I enjoy riding my super bike, training in Systema and horsing around with my family.


Month List

Visitors

Twitter Feed

21. May 10:15
Still can't believe that they used american actors in Invictus. Just doesn't fit!

17. May 17:12
@UnexpectedPippa only 3? "Don't touch me on my studio!"

17. May 17:12
@SaartjieJoan if you look around you might see many forks hanging out of eye sockets

17. May 17:09
@SaartjieJoan That truly is amazing HAHAHAHA!