XmlSerializer and Nullable<T>. A recipe.

When I tried to serialize a class with an Double? property as attribute, XMLSerializer died with its usual and oh-so-unhelpful cascade of InvalidOperationExceptions. The actual error message was:

Cannot serialize member ‘SomeValue’ of type System.Nullable`1[System.Double]. XmlAttribute/XmlText cannot be used to encode complex types.

Since XML attributes have very well-defined null semantics, I was pretty stumped, but soon I found the Allow override for XmlSerializer Nullable<T> attribute behavior feature request on Microsoft Connect:

Unfortunately, this change would be too large to take and would be a new feature rather than a bug fix. We are trying to minimize new feature work in the XmlSerializer, partly to reduce regression risk, and focus our effort on the next-generation serialization technology. Unfortunately, we have decided to resolve this as Won’t Fix.

So I went back the the trusty old *Specified property of XmlSerializer and hacked together a micro-pattern to support Nullable<T> for serialization to an XML attribute:


[XmlIgnore]
public double? SomeValue { get; set; }

[XmlAttribute("SomeValue")]
[EditorBrowsable(EditorBrowsableState.Never)]
public double XmlSomeValue { get { return SomeValue.Value; } set { SomeValue= value; } }
[EditorBrowsable(EditorBrowsableState.Never)]
public bool XmlSomeValueSpecified { get { return SomeValue.HasValue; } }

This presents a non-nullable property “XmlSomeValue” to the XMLSerializer, which is only “rendered” to the XML if “XmlSomeValueSpecified” is true. That is, if SomeValue is not null. When deserializing from XML, SomeValue is only set when the XML attribute exists, else it keeps its default null value.

For code-hygenic reasons I added the EditorBrowsable attribute on the Xml* properties to avoid cluttering intellisense and similar tools.

Leave a Reply