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

时间:2012-10-31 14:14:43

标签: c# xml-serialization xmlserializer defensive-programming

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

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

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

我正在从外部源接收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);

......一切正常。

然而,昨晚,他们给我发了一些类似 this 的XML,而我的反序列化失败了(应该这样):<Foo Bar="" />

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

2 个答案:

答案 0 :(得分:4)

你可以设置这样的枚举,所以这会将enum的值设置为Unknown = 0,有点像默认值

public enum Foo
{
   [XmlEnum(Name = "")]
   Unknown =0,
   [XmlEnum(Name = "Single")]
   One,
   [XmlEnum(Name = "Double")]
   Two   
}

更多细节检查:XmlEnumAttribute Class

答案 1 :(得分:0)

击落XmlSerializer .. 使用 LINQ2XML 执行此简单任务

XElement doc=XElement.Load("yourStreamXML"); 

List<Foo> yourList=doc.Descendants("Foo")
.Select(x=>
new Foo
{
    Bar=(Enum.GetNames(typeof(Value)).Contains(x.Attribute("Bar").Value))?((this.Value)x.Attribute("Bar")):(this.Value.ValueOne);
}
).ToList<Foo>();

所以,我基本上是这样做的

if(Enum.GetNames(typeof(Value)).Contains(x.Attribute("Bar").Value))
//if the xml bar value is a valid enum
    Bar=(this.Value)x.Attribute("Bar");
else//xml bar value is not a valid enum..so use the default enum i.eValueOne
    Bar=this.Value.ValueOne;