XmlSerializer: Hidden features (xxxSpecified)

Der XmlSerializer ist ein sehr schönes und mächtiges Werkzeug und wird von mir oft verwendet. Heute bin ich über ein Feature gestolpert, was mir noch nicht bewusst war: Man kann einzelne public Members dynamisch steuern, ob diese serialisiert werden sollen oder nicht.

Das ganze funktioniert dann, wenn es ein public Field oder Property gibt, welches genau gleich heissen muss wie das danamisch zu serialisierendes Element nur mit der Endung “Specified”. Also:

  public class Foo
  {
    public string Value;

    [XmlIgnore] 
    public bool ValueSpecified; // Dieses gibt an, ob das obige Field serialisiert wird
  }

Gesteuert wird dies dann über das “ValueSpecified” Field:

using System;
using System.IO;
using System.Xml.Serialization;

namespace ConsoleApplication_VS2010
{
  public class Foo
  {
    public string Value;

    [XmlIgnore] 
    public bool ValueSpecified; // Dieses gibt an, ob das obige Field serialisiert wird

    public override string ToString()
    {
      return string.Format("Value: '{0}', ValueSpecified: {1}", Value ?? "(null)", ValueSpecified);
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      var f = new Foo();
      f.Value = "Text";

      using(var s = new StringWriter())
      {
        var ser = new XmlSerializer(typeof (Foo));
        ser.Serialize(s, f);
        var str = s.ToString();
        Console.WriteLine(str);
        using(var sr = new StringReader(str))
        {
          Console.WriteLine(ser.Deserialize(sr));
        }
      }
      Console.WriteLine();

      f.ValueSpecified = true;
      using (var s = new StringWriter())
      {
        var ser = new XmlSerializer(typeof(Foo));
        ser.Serialize(s, f);
        var str = s.ToString();
        Console.WriteLine(str);
        using (var sr = new StringReader(str))
        {
          Console.WriteLine(ser.Deserialize(sr));
        }
      }
    }
  }
}

Die Ausgabe ist dann (Anm.: ?xml header entfernt):

<Foo />
Value: '(null)', ValueSpecified: False

<Foo>
  <Value>Text</Value>
</Foo>
Value: 'Text', ValueSpecified: True

Fazit: Wieder etwas dazugelernt…

Leave a Reply

Your email address will not be published.

Captcha *