I’ve dealt with this before, but I’m bumping into it again so I figured I’d blog about it to vent a little…
If you implement IXmlSerializable to customize the output of your type when it partakes in XML serialization, you can’t even decorate it with XmlRootAttribute. This basically means that if your type is the root of an object graph that needs to be serialized you have to explicitly pass an instance of XmlRootAttribute to the XmlSerializer via a constructor overload. Umm… what if I want to just deal with IXmlSerializable types abstractly? How do I know what the heck I’m supposed to setup for the root attribute? It needs to be the right element name in the right namespace or else it won’t result in a valid instance document.
It’s like whoever designed the code-path for IXmlSerializable support within the XmlSerializer just decided that: “Hey, they shouldn’t use the serialization attributes if they use custom serialization, so I’m just gonna error if any are used!”. That’s great, except you forgot that XmlSerializer always writes the start element out before handing control over to IXmlSerializable::WriteXml, so leaving XmlRootAttribute usable would make sense.
I have a work around, but it requires me to configure all types that I might ever serialize up front which defeats the entire purpose of dealing with these things generically. Damn this sucks. Yet another example of almost getting it right. Anyway, if I’m missing anything, please leave a comment and set me straight.
Update: FWIW, I checked last night and the .NET 2.0 (Whidbey) version of the XmlSerializer actually works as one would expect, honoring the presense of XmlRootAttribute even on IXmlSerializable isntances. Also, according to a comment from Matt Tavis, full support has been “re-enabled” for all attributes that still make sense even in the IXmlSerializable scenario.