I want to share with you something I found very useful. In this post I’ll show how to use the WCF Serializer to serialize and deserialize objects into XML files. I’ve learn that from my coworker Edgardo Rossetto.

I’ve wrote in the previous post about WCF, to send an receive messages WCF needs to serialize and deserialize objects, to do this in the assembly System.Runtime.Serialization there is a class called DataContractSerializer

public sealed class DataContractSerializer : System.Runtime.Serialization.XmlObjectSerializer
    Member of System.Runtime.Serialization

Summary:
Serializes and deserializes an instance of a type into an XML stream or document using a supplied data contract. This class cannot be inherited.

So, let’s see an example…

The first step is tag our model classes with DataContract and DataMember attributes.

using System.Collections.ObjectModel;
using System.Runtime.Serialization;

[DataContract]
public class Person
{
    private Collection<Address> address;

    [DataMember]
    public int Id { get; set; }

    [DataMember(IsRequired=false)]
    public string Name { get; set; }

    [DataMember]
    public Collection<Address> Address
    {
        get
        {
            if (this.address == null)
            {
                this.address = new Collection<Address>();
            }

            return this.address;
        }
        set
        {
            this.address = value;
        }
    }
}


[DataContract]
public class Address
{



    [DataMember]
    public string Street { get; set; }



    [DataMember]
    public int Number { get; set; }
}

Notice, we want to serialize and deserialize the Person class, but it has a one-to-many relationship with Address class, so both classes should be tagged as DataContracts and the members we want to serialize should be tagged with DataMember attribute, a little detail to denote is that the property Name of Person class is defined as not required, this means that we don’t need to have a value for this property.

After we have all our classes tagged we need to create a helper class to work with DataContractSerializer. Usually this class is defined with generic methods, because in that way we can use the same class to serialize and deserialize any kind of objects.

using System;
using System.Runtime.Serialization;
using System.Xml;

public class ModelSerializer
{
    public virtual TModel Deserialize<TModel>(string path)
    {
        XmlReader reader = XmlReader.Create(path);

        DataContractSerializer serializer = new DataContractSerializer(typeof(TModel));
        TModel result = (TModel)serializer.ReadObject(reader);

        return result;
    }

    public virtual void Serialize<TModel>(TModel model, string path)
    {
        XmlWriter writer = XmlWriter.Create(path);

        DataContractSerializer serializer = new DataContractSerializer(typeof(TModel));
        serializer.WriteObject(writer, model);

        writer.Flush();
    }
}

This class has two generic methods, Serialize and Deserialize, as you can see both methods uses the DataContractSerializer giving as parameter the generic type TModel.

The implementation is very simple, you only need an XmlReader or an XmlWritter, to provide infrastructure to write or read the XML file, and that’s all. Now we can serialize, into an XML file, any instance of any class tagged as DataContract and deserialize it from an XML file.

This is an example of using, in an Console Application we create an instance of Person class, set some data and we serialize using out ModelSerializer.

class Program
{
    static void Main(string[] args)
    {
        var person = new Person()
        {
            Id = 1,
            Name = "Franz Xaver Sussmayr",
        };

        person.Address.Add(new Address()
        {
            Street = "Schwanenstadt",
            Number = 1766
        });

        person.Address.Add(new Address()
        {
            Street = "Vienna",
            Number = 1803
        });

        var serializer = new ModelSerializer();

        serializer.Serialize<Person>(person, "C:/person.xml");
    }
}

And the result is an person.xml file with this content:

<?xml version="1.0" encoding="utf-8"?>
<Person xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://schemas.datacontract.org/2004/07/WcfSerialization">



  <Id>1</Id>
  <Name>Franz Xaver Sussmayr</Name>

  <Address>

    <Address>

      <Number>1766</Number>

      <Street>
Schwanenstadt
</Street>

    </Address>


    <Address>
      <Number>1803</Number>
      <Street>Vienna</Street>
    </Address>
  </Address>

</Person>

To deserialize this file is even more easy…

class Program
{
    static void Main(string[] args)
    {
        var serializer = new ModelSerializer();

        var person = serializer.Deserialize<Person>("C:/person.xml");
    }
}

quickwatch

Leave a Reply