Использование XML-декоров для указания значений по умолчанию во время де-сериализации

У меня проблема десериализации некоторого XML; XML, предоставленный третьей стороной, довольно многословный, поэтому, если для определенного элемента нет значения, оно будет содержать и пустым элементом (например, <element1 />).

Это проблема для некоторых элементов, например тех, которые предназначены для хранения целых чисел. У меня есть контроль над третьей стороной, поэтому я могу либо заставить их указать значение по умолчанию (<myinteger>0</myinteger>), либо я могу заставить их полностью опустить эти элементы. Обе эти проблемы должны быть устранены.

Однако в будущем могут возникнуть ситуации, когда у нас не так много контроля - в этом случае есть ли способ указать, возможно, через украшение значение по умолчанию?

    [XmlElement("myinteger")=0???]
    public int MyInteger
    {
        get
        {
            return myInteger;
        }
        set
        {
            myInteger= value;
        }
    }

Ответы

Ответ 1

XmlSerializer поддерживает [DefaultValue], но использует его во время сериализации. Во время десериализации он просто запускает конструктор, затем принимает входящие значения и применяет их. Таким образом, общий подход заключается в использовании конструктора (или инициализатора поля):

public Foo() {
    Bar = 4;
}
[DefaultValue(4), XmlAttribute("bar")]
public int Bar {get;set;}

Тем не менее; XmlSerializer интерпретация этого не означает "предоставить пустой элемент", а скорее "опустить элемент (/attribute)". Даже int? не отображается на "пустой". Для обработки пустых элементов вам придется обрабатывать его как строку. Что является уродливым.

Ответ 2

Украшение с использованием [DefaultValue] не кажется полным решением, так как оно не работает всегда. Еще одно простое решение (может не быть чистым)

public string _sourceSubFolderName;
    [DefaultValueAttribute("")]
    [XmlElement("SourceSubFolderName")]
    public string SourceSubFolderName
    {
        get { return string.IsNullOrEmpty(_sourceSubFolderName) ? 
               string.Empty : _sourceSubFolderName; }
        set { _sourceSubFolderName = value; }
    }