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.