Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serialize string property as attribute, even if string is empty

public class Hat
{
    [XmlTextAttribute]
    public string Name { get; set; }
    [XmlAttribute("Color")]
    public string Color { get; set; }
}

var hat1 = new Hat {Name="Cool Hat", Color="Red"};
var hat2 = new Hat {Name="Funky Hat", Color=null};

This is what I get (notice missing color-attribute on Funky Hat):

<Hats>
 <Hat Color="Red">Cool Hat</Hat>
 <Hat>Funky Hat</Hat>
</Hats>

This is what I want:

<Hats>
 <Hat Color="Red">Cool Hat</Hat>
 <Hat Color="">Funky Hat</Hat>
</Hats>

How can I force the serializer to create an empty attribute in stead of leaving it out?

EDIT:

Turns out I am an idiot and created an example that contained an error, because I wanted to simplify the code for the example.

If the value of color is "" (or string.empty), it is actually serialized as an empty attribute. However, I really had a null value, not an empty string - hence it was left out.

So the behavior I wanted was actually already the behavior of the example I created.

Sorry, guys!

like image 378
Kjensen Avatar asked Apr 29 '11 17:04

Kjensen


3 Answers

Try using List<Hat> as the container. Using this:

var hats = new List<Hat>
    {
        new Hat { Name = "Cool Hat", Color = "Red" }, 
        new Hat { Name = "Funky Hat", Color = string.Empty }
    };

using (var stream = new FileStream("test.txt", FileMode.Truncate))
{
    var serializer = new XmlSerializer(typeof(List<Hat>));
    serializer.Serialize(stream, hats);
}

I get this:

<?xml version="1.0"?>
<ArrayOfHat xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Hat Color="Red">Cool Hat</Hat>
  <Hat Color="">Funky Hat</Hat>
</ArrayOfHat>
like image 151
Teoman Soygul Avatar answered Nov 02 '22 17:11

Teoman Soygul


You could try setting the Specified property to true. Also, I believe you can use a ##Specified property to control serialization, like this:

[XmlAttribute("Color")]
public string Color { get; set; }
[XmlIgnore]
public bool ColorSpecified { get { return true; } }    // will always serialize

Or you can serialize as long as it is not null:

[XmlIgnore]
public bool ColorSpecified { get { return this.Color != null; } }
like image 31
mellamokb Avatar answered Nov 02 '22 16:11

mellamokb


There are two ways you can do this.

You could use [XmlElement(IsNullable=true)], which will force the null value to be recognized.

You could also use String.Empty instead of "". This is recognized as an empty string and not a null.

like image 42
Alex Russell Avatar answered Nov 02 '22 17:11

Alex Russell