Serializing and deserializing multiple generic collections using DataContractSerializer

The DataContractSerializer class is the successor of the XmlSerializer class. Introduced together with WCF. This one is also being used by WCF for serialization by default. You can of course always switch back to the good old XmlSerializer if you want to.

Anyway, if you wanted to serialize a collection with the XmlSerializer you had to use the XmlArrayAttribute

With the DataContractSerializer you get the CollectionDataContractAttribute class. Personally, I think that serializing a generic list via the DataContractSerializer is easier then with the XmlSerializer. Even with the DataContractSerializer I think they could have done it easier. You’ll see what I mean in a minute.

Let’s look at some code.

The example

The example will be a simple to-do list. You can specify a name, a due data and multiple tags.

Creating the necessary classes

   1: [DataContract(Name = "TodoList", Namespace = "http://www.mshelp.be")]

   2: public class TodoList

   3: {

   4:     [DataMember(Name = "Todos")]

   5:     public InternalTodoList Todo { get; set; }

   6:     public TodoList()

   7:     {

   8:         Todo = new InternalTodoList();

   9:     }

  10: }

  11: [DataContract(Name = "Todo")]

  12: public class Todo

  13: {

  14:     public Todo()

  15:     {

  16:         Name = String.Empty;

  17:         DueDate = DateTime.Now;

  18:         Tags = new TagList();

  19:     }

  20:     [DataMember(Name = "Name")]

  21:     public string Name { get; set; }

  22:     [DataMember(Name = "DueDate")]

  23:     public DateTime DueDate { get; set; }

  24:     [DataMember(Name = "Tags")]

  25:     public TagList Tags { get; set; }

  26: }

  27: [CollectionDataContract(ItemName = "Tag")]

  28: public class TagList : List<string> { }

  29:  

  30: [CollectionDataContract(ItemName = "Todo")]

  31: public class InternalTodoList : List<Todo> { }

The class TodoList will contain all the different todo’s and the Todo class contains the properties we already discussed. As you can see I also have two other classes. The TagList and the InternalTodoList, both marked with the CollectionDataContract attribute. You also see that these classes contain the generic lists. I did this because you can only add the CollectionDataContract attribute to a class or struct.

How to Serialize

As you can see I use the XmlDictionaryWriter class, which was also introduced with .NET 3.0.

   1: static void SerializeTodoList()

   2: {

   3:     var dcs = new DataContractSerializer(typeof(TodoList));

   4:     var ds = new FileStream(@"c:\MyTodoList.xml",FileMode.Create);

   5:     var xdw = XmlDictionaryWriter.CreateTextWriter(ds, Encoding.UTF8);

   6:     dcs.WriteObject(xdw, _myTodoList);

   7:     xdw.Flush();

   8:     someStream.Flush();

   9: }

How to Deserialize

For the desrialization we’ll use the XmlDictionaryReader class together with the DataContractSerializer.

   1: static void DeserializeTodoList()

   2: {

   3:     var dcs = new DataContractSerializer(typeof(TodoList));

   4:     var ds = new FileStream(@"c:\MyTodoList.xml", FileMode.Open);

   5:     var xdr = XmlDictionaryReader.CreateTextReader(ds, new XmlDictionaryReaderQuotas());

   6:     _myTodoList = (TodoList)dcs.ReadObject(xdr);

   7: }

Testing the code

Now for a simple test, let’s add some to-do’s. Don’t forget to define the _myTodoList, which is of course an instance of the TodoList class.

   1: static void InitTodoList()

   2: {

   3:     _myTodoList = new TodoList();

   4:     var todo1 = new Todo {Name = "Fix some issues"};

   5:     var tlist1 = new TagList {"fix", "issues"};

   6:     todo1.Tags = tlist1;

   7:     _myTodoList.Todo.Add(todo1);

   8:  

   9:     var todo2 = new Todo {Name = "Fix stuff"};

  10:     var tlist2 = new TagList {"fix", "stuff"};

  11:     todo2.Tags = tlist2;

  12:     _myTodoList.Todo.Add(todo2);

  13: }

The aforementioned code will generate the following XML.

   1: <TodoList xmlns="http://www.mshelp.be" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">

   2: <Todos xmlns:a="http://schemas.datacontract.org/2004/07/CollectionDataContractAtt">

   3: <a:Todo>

   4: <a:DueDate>2009-06-20T15:19:57.196+02:00</a:DueDate> 

   5: <a:Name>Fix some issues</a:Name> 

   6: <a:Tags>

   7: <a:Tag>fix</a:Tag> 

   8: <a:Tag>issues</a:Tag> 

   9: </a:Tags>

  10: </a:Todo>

  11: <a:Todo>

  12: <a:DueDate>2009-06-20T15:19:57.201+02:00</a:DueDate> 

  13: <a:Name>Fix stuff</a:Name> 

  14: <a:Tags>

  15: <a:Tag>fix</a:Tag> 

  16: <a:Tag>stuff</a:Tag> 

  17: </a:Tags>

  18: </a:Todo>

  19: </Todos>

  20: </TodoList>

Hope this post was informative and if you have comments, remarks. Please let me know, any constructive feedback is welcome.

kick it on DotNetKicks.com Shout it Progg itvote it on WebDevVote.com


No comments yet. Be the first.

Leave a reply

*
To prove you're a person (not a spam script), type the security word shown in the picture. Click on the picture to hear an audio file of the word.
Click to hear an audio file of the anti-spam word