Wednesday, November 26, 2003 2:01 PM Shawn A. Van Ness

XmlSerializer does not play nice with others. By design.

There are two types of personalities, among software engineers -- two types of personalities in general, really -- the aggressively controlling, impatient "Type A" personalities, and the more passive, easy-going "Type B" personalities.

As one of the first people to step up with a custom code-generator for strongly-typed collection classes, I lean strongly toward the former.  But even I know when I'm beat.  For example, when faced with a reflection-based serialization architecture which requires

  • public, parameterless constructors on all my classes
  • public accessibility on all my fields and properties
  • never creating a circular loop of object references
  • never caring about the instance-identity of my objects
  • never caring about the base-class type identity of my objects

I know that I have no prayer, no hope of applying this technology directly to the code I need to write, in order to do my job.  No cute tricks, magic attributes, or fancy design patterns are going to save the situation.

I'm talking, of course, about XML Serialization: the System.Xml.Serialization.XmlSerializer class.  It does not play nice with the other classes in your project!  Consider yourself warned.

Now, we can either whine about this, or we can treat this crisis as an opportunity -- if we accept, from day one, that we can not apply XML Serialization attributes directly to the meat of our code, and that we'll have to generate and maintain a whole set of classes tailored for just this purpose... why not factor those classes out into a separate assembly?  This gives us a nice, lightweight, effortlessly redistributable wrapper for reading and writing our file format.

Further, if we place those XML-serializable classes into their own namespace (I like to tack on ".Serialization") we can easily reference those classes in richer, fully-functional business logic classes of the same name -- woohoo, crisitunity!

Here's an example of how one might leverage XML Serialization in a WinForms application:

Foo.exe
A hypothetical WinForms app for editing .foo documents -- contains types mostly in the Jitsu.Foo namespace, including Jitsu.Foo.Document, a high-level representation of the .foo document model, including normalized references, lots of validation logic, a dirty bit, modification events, and so forth.
Jitsu.Foo.Serialization.dll
.NET assembly containing the XML Serialization code for .foo documents -- types in the Jitsu.Foo.Serialization namespace, containing almost no logic at all.  The richer classes (like Jitsu.Foo.Document, above) handle saving/loading themselves into/outof these raw serialization types.

I tend to think of defining an XML layout with C# classes in much the same way we used to define binary file formats with structs, in C.  For example, have a look at BITMAPFILEHEADER in WinGdi.h or IMAGE_NT_HEADERS in WinNT.h -- used to describe the formats of the file-headers for bitmap files and PEFF executable files, respectively.  The concept is identical -- the only difference is in the medium used to distribute the type information: header files for C, assemblies for .NET.

Like the file-formatting structs we see in the Win32 headers, I typically don't write one line of executable code into my XML-serializable types.  I even incur the wrath of FxCop by using public fields instead of properties (this may be the one and only justifiable case for that taboo).  So far, the only case I've encountered for mixing procedural code with XML Serialization is to perform custom formatting of date and time elements -- currently, XML Serialization only supports one format for System.DateTime: ISO-8601 local time.  If you want something else, like UTC time, you'll have to hide the DateTime field behind a property getter/setter of type string.

Comments

# re: XmlSerializer does not play nice with others. By design.

Wednesday, November 26, 2003 5:15 PM by Drew Marsh

All we can do is hope that Indigo's new XmlFormatter architecture gets here ASAP. It's exactly what everyone wants/expects the XmlSerializer to be.

# re: XmlSerializer does not play nice with others. By design.

Wednesday, November 26, 2003 5:25 PM by Thomas Tomiczek

Aboslutly right with your statement.

I think a LOT of people totally forget that software is written with a CAUSE. And the CAUSE of XML Serializer was NOT to enable business object serialization, but ti make it WAY easier to work with XML files (instead of CodeDOM). Use it as such, and it works absolutly like a charm. Dont - and, well, your fault.

# re: XmlSerializer does not play nice with others. By design.

Wednesday, November 26, 2003 7:14 PM by JosephCooney

When I wanted to serialize a class to XML I just rolled my own serialization code. It was either that or butcher my object model which I didn't want to do. It turned out to be about 100 lines of pretty dull code. I wrote about it in my blog here. http://dotnetjunkies.com/weblog/josephcooney/posts/2760.aspx

I'm not sure what Thomas means by CodeDom....that has almost nothing to do with XML. I assume he means the XML Dom (which could be a case study in how to write an API that is hard to use). If that is the case then I don't exactly agree with him that Serialization was designed to make working with XML documents easier. Does he mean the XML readers/writer?

# re: XmlSerializer does not play nice with others. By design.

Thursday, November 27, 2003 2:15 AM by Clemens Vasters

The XmlSerializer saves me a lot of time and it's quite fast. Good enough for me to live with the restrictions that it imposes on my type design.

# re: XmlSerializer does not play nice with others. By design.

Wednesday, December 10, 2003 3:06 PM by Daniel Cazzulino

"public accessibility on all my fields and properties"
This is a false statement. You only need to make public what you want to get serialized. I agree it could be more flexible, but it's not completely useless. Plus, you can go the IXmlSerializable path and gain full flexibility in how you manage your serialization code.

# re: XmlSerializer does not play nice with others. By design.

Wednesday, December 10, 2003 3:08 PM by Daniel Cazzulino

BTW, your weblog looks quite bad in Mozilla Firebird...

# re: XmlSerializer does not play nice with others. By design.

Wednesday, December 10, 2003 4:03 PM by Shawn A. Van Ness

It's not a false statement -- read it again. "a serialization architecture which requires ... public accessibility on all my fields and properties"

The whole topic at hand, here, is serialization. How redundant to expect me to be?

Care to share your CSS? It's fly!
-S

# More on XmlSerializer

Tuesday, January 06, 2004 8:35 PM by TrackBack

Last month, I blogged about XmlSerializer, and the constraints it imposes on the .NET types you'd like to map onto XML structure. I was recently reminded of another limitation of XmlSerializer: it doesn't let you switch your type mappings, on the fly -- for example, in response to a version attribute. And yet. A great many XML document formats use just such an attribute...

# More on XmlSerializer

Wednesday, January 14, 2004 11:28 PM by TrackBack

Last month, I blogged about XmlSerializer, and the constraints it imposes on the .NET types you'd like to map onto XML structure. I was recently reminded of another limitation of XmlSerializer: it doesn't let you switch your type mappings, on the fly -- for example, in response to a version attribute. And yet. A great many XML document formats use just such an attribute...

# [NotSo]DailyBytes.Add(

Wednesday, March 24, 2004 6:49 PM by TrackBack

# re: Limitation of System.Xml.XmlSerializer... planned or error?

Thursday, May 13, 2004 8:42 AM by TrackBack

# Type fidelity in XML

Sunday, October 03, 2004 10:22 AM by TrackBack

# Type fidelity in XML

Sunday, October 03, 2004 10:30 AM by TrackBack