XmlSerializer и обнуляемые атрибуты - PullRequest
30 голосов
/ 15 июля 2010

У меня есть класс с многочисленными Nullable свойствами, которые я хочу, чтобы они были сериализуемы в XML как атрибуты.Это, очевидно, нет-нет, так как они считаются «сложными типами».Таким образом, вместо этого я реализую шаблон * Specified, в котором я создаю дополнение * Value и * Specified свойство следующим образом:

[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; }
}

Что работает нормально - если свойство 'Age' имеет значение, оно сериализуетсякак атрибут.Если оно не имеет значения, оно не сериализуется.

Проблема в том, что, как я уже говорил, в моем классе много Nullable-ов, и этот шаблон просто делает вещи беспорядочными и неуправляемыми.

Я надеюсь, что есть способ сделать Nullable более дружественным к XmlSerializer.Или, в противном случае, способ создать замену Nullable, которая есть.

У кого-нибудь есть идеи, как мне это сделать?

Спасибо.

Ответы [ 2 ]

17 голосов
/ 15 июля 2010

У меня была похожая проблема с некоторым кодом, над которым я работал, и я решил просто использовать строку для свойства, которое я сериализовал и десериализовал.Я закончил что-то вроде этого:

[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;
10 голосов
/ 15 июля 2010

Реализуйте интерфейс IXmlSerializable в своем классе.Затем вы можете обрабатывать особые случаи, такие как обнуляемые, в методах ReadXML и WriteXML. На странице документации MSDN есть хороший пример. .

 
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
}
...