Can XmlSerializer deserialize into a Nullable<int>?
-
08-07-2019 - |
Question
I wanted to deserialize an XML message containing an element that can be marked nil="true"
into a class with a property of type int?
. The only way I could get it to work was to write my own NullableInt
type which implements IXmlSerializable
. Is there a better way to do it?
I wrote up the full problem and the way I solved it on my blog.
Solution
I think you need to prefix the nil="true" with a namespace in order for XmlSerializer to deserialise to null.
<?xml version="1.0" encoding="UTF-8"?>
<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="array">
<entity>
<id xsi:type="integer">1</id>
<name>Foo</name>
<parent-id xsi:type="integer" xsi:nil="true"/>
OTHER TIPS
My fix is to pre-process the nodes, fixing any "nil" attributes:
public static void FixNilAttributeName(this XmlNode @this)
{
XmlAttribute nilAttribute = @this.Attributes["nil"];
if (nilAttribute == null)
{
return;
}
XmlAttribute newNil = @this.OwnerDocument.CreateAttribute("xsi", "nil", "http://www.w3.org/2001/XMLSchema-instance");
newNil.Value = nilAttribute.Value;
@this.Attributes.Remove(nilAttribute);
@this.Attributes.Append(newNil);
}
I couple this with a recursive search for child nodes, so that for any given XmlNode (or XmlDocument), I can issue a single call before deserialization. If you want to keep the original in-memory structure unmodified, work with a Clone() of the XmlNode.
The exceptionally lazy way to do it. It's fragile for a number of reasons but my XML is simple enough to warrant such a quick and dirty fix.
xmlStr = Regex.Replace(xmlStr, "nil=\"true\"", "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:nil=\"true\"");