Deserializing empty xml attribute value into nullable int property using XmlSerializer Deserializing empty xml attribute value into nullable int property using XmlSerializer xml xml

Deserializing empty xml attribute value into nullable int property using XmlSerializer


This should work:

[XmlIgnore]public int? Age { get; set; }[XmlElement("Age")]public string AgeAsText{  get { return (Age.HasValue) ? Age.ToString() : null; }   set { Age = !string.IsNullOrEmpty(value) ? int.Parse(value) : default(int?); }}


I solved this problem by implementing IXmlSerializable interface. I did not found easier way.

Here is the test code sample:

[XmlRoot("root")]public class DeserializeMe {    [XmlArray("elements"), XmlArrayItem("element")]    public List<Element> Element { get; set; }}public class Element : IXmlSerializable {    public int? Value1 { get; private set; }    public float? Value2 { get; private set; }    public void ReadXml(XmlReader reader) {        string attr1 = reader.GetAttribute("attr");        string attr2 = reader.GetAttribute("attr2");        reader.Read();        Value1 = ConvertToNullable<int>(attr1);        Value2 = ConvertToNullable<float>(attr2);    }    private static T? ConvertToNullable<T>(string inputValue) where T : struct {        if ( string.IsNullOrEmpty(inputValue) || inputValue.Trim().Length == 0 ) {            return null;        }        try {            TypeConverter conv = TypeDescriptor.GetConverter(typeof(T));            return (T)conv.ConvertFrom(inputValue);        }        catch ( NotSupportedException ) {            // The conversion cannot be performed            return null;        }    }    public XmlSchema GetSchema() { return null; }    public void WriteXml(XmlWriter writer) { throw new NotImplementedException(); }}class TestProgram {    public static void Main(string[] args) {        string xml = @"<root><elements><element attr='11' attr2='11.3'/><element attr='' attr2=''/></elements></root>";        XmlSerializer deserializer = new XmlSerializer(typeof(DeserializeMe));        Stream xmlStream = new MemoryStream(Encoding.ASCII.GetBytes(xml));        var result = (DeserializeMe)deserializer.Deserialize(xmlStream);    }}


I've been messing around with serialization a lot myself of late and have found the following articles and posts helpful when dealing with null data for value types.

The answer to How to make a value type nullable with XmlSerializer in C# - serialization details a pretty nifty trick of the XmlSerializer. Specifically, the XmlSerialier looks for a XXXSpecified boolean property to determine if it should be included which allows you to ignore nulls.

Alex Scordellis asked a StackOverflow question which received a good answer. Alex also did a good writeup on his blog about the problem he was trying to solve Using XmlSerializer to deserialize into a Nullable<int>.

The MSDN documentation on Xsi:nil Attribute Binding Support is also useful. As is the documentation on IXmlSerializable Interface, though writing your own implementation should be your last resort.