XmlSerializer - 反序列化枚举时如何设置默认值?

Nei*_*ilD 5 c# defensive-programming xml-serialization xmlserializer

我有一个看起来像这样的类(大大简化):

public class Foo
{
    public enum Value
    {
        ValueOne,
        ValueTwo
    }

    [XmlAttribute]
    public Value Bar { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我从外部源接收 XML 文件。他们的文档指出,Foo 元素的 Bar 属性中只会有“ValueOne”或“ValueTwo”(他们不提供 XSD)。

所以,我像这样反序列化它:

 var serializer = new XmlSerializer(typeof(Foo));
 var xml = "<Foo Bar=\"ValueTwo\" />";
 var reader = new StringReader(xml);

 var foo = (Foo)serializer.Deserialize(reader);
Run Code Online (Sandbox Code Playgroud)

...这一切都有效。

然而,昨晚,他们向我发送了一些如下所示的 XML 而我的反序列化失败了(理应如此):<Foo Bar="" />

有没有一种好的方法可以围绕这个进行防御性编码?理想情况下,我想说“如果这里出现问题,默认为 ValueOne”。我不想丢弃整个 XML 文件,因为单个属性被破坏了。

Sav*_*ave 1

您可以通过创建具有相同 XmlAttribute 名称的另一个属性来手动解析枚举值:

public enum Value
{
    // Default for unknown value
    Unknown,
    ValueOne,
    ValueTwo
}

[XmlIgnore]
public Value Bar { get; set; }

[XmlAttribute("Bar")]
public string _Bar
{
    get { return this.Bar.ToString(); }
    set { this.Bar = Enum.TryParse(value, out Value enumValue) ? enumValue : Value.Unknown; }
}
Run Code Online (Sandbox Code Playgroud)

用法和之前一样

var serializer = new XmlSerializer(typeof(Foo));
var xml = "<Foo Bar=\"invalid value\" />";
var reader = new StringReader(xml);
var foo = (Foo)serializer.Deserialize(reader);
Run Code Online (Sandbox Code Playgroud)