Main image
30th June
2010
written by Chris

Not this kind of XML

VirPack has me working on an application that needs a user administered list of options for people to choose from. It’s a fairly simple thing that doesn’t require relational tables so I thought I’d toss it into XML.

Now, C# deals with XML really well. Almost everything, if you just ask nicely, will be quickly and easily packed off into XML the framework with just a few lines of code.

String path = Server.MapPath("~\\myfile.xml");
using (FileStream sourceFile = new FileStream(Server.MapPath(path), FileMode.Create, FileAccess.Write))
        {
            XmlSerializer serializer = new XmlSerializer(typeof(Foo));
            serializer.Serialize(sourceFile, bar);
        }
        bar = null;
        using (System.IO.FileStream sourceFile = new System.IO.FileStream(path, System.IO.FileMode.Open, System.IO.FileAccess.Read))
        {
            System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(Foo));
            Foo bar= serializer.Deserialize(sourceFile) as Foo;
        }

As simple as that I’ve packed my class off to be serialized and then unserialized it. Three lines of code is hard to beat for XML serialization and deserialization. “Foo” is a user defined type, however, and my particular task being the population of a drop-down list, no such complexity was required. Yet, when I tried to feed a List of ListItems into the Serializer everything broke.

//This breaks
System.Xml.Serialization.XmlSerializer listSerializer = new System.Xml.Serialization.XmlSerializer(typeof(List));
//This too
System.Xml.Serialization.XmlSerializer typedListSerializer = new System.Xml.Serialization.XmlSerializer(typeof(List<ListItem>));

This has to do with how C# deals with collections. Serialization requires a root level node and a collection, despite having an appearance of such, has no root level information. It is a collection, not a collection bounded by something else and XML serialization requires that something else.

So C# has a hackish workaround. The ListItemContainer class is a simple type that contains a List of ListItems.

//This works
System.Xml.Serialization.XmlSerializer listSerializer = new System.Xml.Serialization.XmlSerializer(typeof(ListItemContainer));

Of course, not everything you’ll wish to serialize in a list will be a list item, but the fact that C# had to create it’s own little wrapper class should be a clue for developers. Getting a collection into XML requires a wrapper class; it’s as simple as that.

Would it have killed them to document that though?

Comments are closed.