Jules
Jules

Reputation: 1081

Deserialise missing XML attribute to Nullable type

There are various solutions for serialising Nullable types on SO but what i need is a solution for deserialising to a nullable type. The Specified and ShouldSerailise techniques dont seem to apply to deserialising.

So if my XML document is missing an attribute I want the int in the class to be null not 0.

Unfortunately you cant serialise directly to a nullable int because the serializes throws a reflection error.

So in the example below i want result2.SomeInt to be null and result1.SomeInt = 12

class TestProgram
{
    public static void Main(string[] args)
    {
        XmlSerializer deserializer = new XmlSerializer(typeof(Result));

        Stream xmlStream = new MemoryStream(Encoding.ASCII.GetBytes(docWithVal().InnerXml));
        var result1 = (Result)deserializer.Deserialize(xmlStream);

        Stream xmlStream2 = new MemoryStream(Encoding.ASCII.GetBytes(docWithoutVal().InnerXml));
        var result2 = (Result)deserializer.Deserialize(xmlStream2);
    }

    public static XmlDocument docWithoutVal()
    {
        var doc = new XmlDocument();
        doc.LoadXml(@"<Result/>");
        return doc;
    }

    public static XmlDocument docWithVal()
    {
        var doc = new XmlDocument();
        doc.LoadXml(@"<Result SomeInt = ""12""/>");
        return doc;
    }
}

[Serializable]
public class Result
{
    [XmlAttribute]
    public int? SomeInt { get; set; }
}

Upvotes: 1

Views: 4913

Answers (1)

Furqan Safdar
Furqan Safdar

Reputation: 16698

You can infact use the Specified techniques after deserialization. Modify your Result class this way:

[Serializable]
public class Result
{
    [XmlAttribute]
    public int SomeInt { get; set; }

    [XmlIgnore]
    public bool SomeIntSpecified;
}

Now use this logic after deserialization for Nullable types:

var value = SomeIntSpecified ? SomeInt : null;

OR you can also implement IXmlSerializable in your Result class:

[Serializable]
public class Result : IXmlSerializable
{
    public int? SomeInt { get; set; }

    #region IXmlSerializable members

    public void WriteXml(XmlWriter writer)
    {
        if (SomeInt != null) { writer.WriteValue(writer); }
    }

    public void ReadXml(XmlReader reader)
    {
        int result;
        if (int.TryParse(reader.GetAttribute("SomeInt"), out result))
            SomeInt = result;
    }

    public XmlSchema GetSchema()
    {
        return (null);
    }

    #endregion
}

Reference: Using XmlSerializer to deserialize into a Nullable

Upvotes: 1

Related Questions