Friday, December 31, 2010

Joys of XML Serialization

Love it or hate it, XML is everywhere and for data and objects, it can be extremely useful.

On one of my last projects, a colleague introduced me to the useful XSD2Code project, which creates a .Net object from an XSD. This made it easy for him to build a structure that could be compiled into code to ensure everyone followed the same structure. This is extremely valuable if someone gives you an XSD as a format to write to and you want to populate it using an object.

In a more recent project, we needed to share details from a component with another calling application via a web service. Enter XMLSerializer, the .Net equivalent of taking an object and dumping it into XML.

Dim s As XmlSerializer = New XmlSerializer(Object)
Dim w As New StringWriter()


s.Serialize(w, Object)
return w.tostring

Sounds great, right? It was for a short time, but as the object got bigger, it contained more collections and references to other objects. Eventually, the Serialize method took up 100% of CPU Usage and never finished. Of course, we couldn't find the problem right off the bat so it caused lots of grief.

(without going into too much detail showcasing my ignorance on all of the specifics, XMLSerializer uses reflection to identify all of the public properties of an object and then outputs them to an XML file - if the object has a lot of objects or collections within it, it can cause a huge drain on the whole process).

Certain posts call to use the BinaryFormatter instead - which is impossible to read but when you de-serialize it, you get the objects out at the other end.

Dim formatter As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter()


Dim ms As New MemoryStream()


formatter.Serialize(ms, Me)


Dim sXML As String
sXML = System.Convert.ToBase64String(ms.ToArray())

But this makes the string illegible to any non-.Net applications, of which there are many - especially if you plan on building publicly accessible web services.

So I started to go through my initial object and blank out certain properties, so that the serialization would work.

What I didn't realize is I could simply tell the Serializer to ignore certain attributes. Enter the XMLIgnore attribute.

Instead of simply calling New XMLSerializer, I call a method that returns the Serializer but with certain attributes that tell it to ignore specific details.

Function GetSmartSerializer() as XMLSerializer
Dim xOver As New XmlAttributeOverrides()
Dim attrs As New XmlAttributes()


attrs = New XmlAttributes()
attrs.XmlIgnore = True
xOver.Add(GetType(ObjectClass), "MyBigCollectionThatNoOneNeedsToSee", attrs)


Dim xSer As New XmlSerializer(GetType(PRAM_Data.Session), xOver)
Return xSer

With the code above, when the application calls

Dim o as XMLSerializer = GetSmartSerializer()
Dim w As New StringWriter()


s.Serialize(w, Object)
return w.tostring

It now excludes the property "MyBigCollectionThatNoOneNeedsToSee" from the XML.

More details can be found here:
XmlAttributes.XmlIgnore Property (System.Xml.Serialization)

I'm curious though - has anyone else encountered this limitation of the XMLSerializer? What solution have you used?

Wednesday, December 22, 2010

Where are my features?

Here's an innovative way to show your customers where certain features are at in the development cycle.

FreeAgent Depot — A furtive glance behind the wizard's curtain

How well do you communicate with your clients about upcoming features?