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?