XML Serializing Nullable Optional Attribute

Summary

The title of this blog post is a bit of a mouth-full. I do a lot of xml serialization and de-serialization. It’s all part of the new paradigm of using APIs to communicate with other systems over the Internet. One of the annoying “features” of the xml serializer is that it doesn’t support nullable attributes. It’ll serialize nullable elements, but not attributes. So I’m going to show how to serialize nullable attributes and make the attribute optional.

The Problem

Here’s the example code of an XML serializer that will not work

public class House
{
    [XmlElement]
    public List<Room> rooms = new List<Room>();
}

public class Room
{
    [XmlAttribute(AttributeName = "name")]
    public string Name { get; set; }

    [XmlAttribute(AttributeName = "windows")]
    public int? NumberOfWindows { get; set; }       
}

In this instance I’m attempting to serialize a nullable integer named “NumberOfWindows”. My goal is to produce an XML file that looks something like this (I removed the schema info to make this easier to read):

<?xml version="1.0" encoding="utf-8"?>
  <rooms name="kitchen" windows="2" />
  <rooms name="bathroom" windows="0" />
  <rooms name="closet" />
</House>

Notice how the “closet” doesn’t have any windows. For a closet, we’ll assume that a window does not apply. So the windows property must be nullable and it must be optional.

How to Fix it

First, let’s change the Room class so that it will serialize without getting an error. The first thing to note is that we can turn the NumberOfWindows parameter into a string, and treat an empty string as the null value:

public class Room
{
    [XmlAttribute(AttributeName = "name")]
    public string Name { get; set; }

    [XmlIgnore]
    public int? NumberOfWindows { get; set; }

    [XmlAttribute(AttributeName = "windows")]
    public string WindowsSerializable 
    {
        get 
        {
            if (NumberOfWindows != null)
            {
                return NumberOfWindows.ToString();
            }
            else
            {
                return "";
            }
        }
        set
        {
            if (WindowsSerializable != null)
            {
                NumberOfWindows = int.Parse(WindowsSerializable);
            }
        }
    }
}

So the NumberOfWindows variable is checked for null and if it is then return an empty string. That will cause the closet to return: windows=””, which is not quite what we want. But at least it will execute and generate an xml output without causing an error. Also, notice that I put an XmlIgnore on the variable that will be populated, but not used to generate the serialized output.

Now we need to make the NumberOfWindows attribute optional. To make it optional we can add this to the end of the WindowsSerializable getter:

public bool ShouldSerializeWindowsSerializable()
{
    return NumberOfWindows.HasValue;
}

You can also do something like this:

public bool ShouldSerializeWindowsSerializable()
{
    return WindowsSerializable != "";
}

The “ShouldSerialize{varname}” method will output your results for the variable indicated if it returns true. So you can put any fancy logic in this method that you want to show or hide the attribute of your choice.

Where to Get the Code

You can go to my github account and download the sample code by clicking here.

2 thoughts on “XML Serializing Nullable Optional Attribute

Leave a Reply