36

I have a class with numerous Nullable<T> properties which I want to be serializable to XML as attributes. This is apparently a no-no as they are considered 'complex types'. So, instead I implement the *Specified pattern, where I create an addition *Value and *Specified property as follows:

[XmlIgnore]
public int? Age
{
    get { return this.age; }
    set { this.age = value; }
}

[XmlAttribute("Age")]
public int AgeValue
{
    get { return this.age.Value; }
    set { this.age = value; }
}

[XmlIgnore]
public bool AgeValueSpecified
{
    get { return this.age.HasValue; }
}

Which works fine - if the 'Age' property has a value, it is serialized as an attribute. If it doesn't have a value, it isn't serialized.

The problem is that, as I mentioned, a have a lot of Nullable-s in my class and this pattern is just making things messy and unmanageable.

I'm hoping there is a way to make Nullable more XmlSerializer friendly. Or, failing that, a way to create a Nullable replacement which is.

Does anyone have any ideas how I could do this?

Thanks.

Andras Zoltan
  • 41,961
  • 13
  • 104
  • 160
Barg
  • 2,968
  • 7
  • 26
  • 28

2 Answers2

21

I had a similar problem with some code I was working on, and I decided just to use a string for the property I was serializing and deserializing. I ended up with something like this:

[XmlAttribute("Age")]
public string Age
{
    get 
    { 
        if (this.age.HasValue)
            return this.age.Value.ToString(); 
        else
            return null;
    }
    set 
    { 
        if (value != null)
            this.age = int.Parse(value);
        else
            this.age = null;
    }
}

[XmlIgnore]
public int? age;
Soonts
  • 20,079
  • 9
  • 57
  • 130
Curt
  • 444
  • 2
  • 5
13

Implement the IXmlSerializable interface on your class. You can then handle special cases such as nullables in the ReadXML and WriteXML methods. There's a good example in the MSDN documentation page..

 
class YourClass : IXmlSerializable
{
    public int? Age
    {
        get { return this.age; }
        set { this.age = value; }
    }

    //OTHER CLASS STUFF//

    #region IXmlSerializable members
    public void WriteXml (XmlWriter writer)
    {
        if( Age != null )
        {
            writer.WriteValue( Age )
        }
    }

    public void ReadXml (XmlReader reader)
    {
        Age = reader.ReadValue();
    }

    public XmlSchema GetSchema()
    {
        return(null);
    }
    #endregion
}
Sentry
  • 4,102
  • 2
  • 30
  • 38
blachniet
  • 4,323
  • 5
  • 33
  • 34
  • 2
    I guess this will have to do - it'd be nice to be able to tell a 'complex' type to serialize as an attribute. – Barg Jul 15 '10 at 14:03
  • 1
    If you have many properties but only one nullable doesn't this mean manually serializing every property? Is there a good way to do it for just nullable properties? The Proxy property in the answer from @Curt does this but I am thinking an attribute decorator must exist? – Corey Alix Mar 17 '21 at 19:04