【问题标题】:XmlSerializer - How can I set a default when deserializing an enum?XmlSerializer - 反序列化枚举时如何设置默认值?
【发布时间】:2012-10-31 14:14:42
【问题描述】:

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

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,而我的反序列化失败(应该如此):&lt;Foo Bar="" /&gt;

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

【问题讨论】:

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


【解决方案1】:

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

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

更多细节检查:XmlEnumAttribute Class

【讨论】:

  • 嗯...这是一个不错的选择,但它确实需要我提前知道所有潜在的坏值。如果他们发送“”、“ValueThree”或“SomethingTotallyRandom”,我想要一些可以应付的东西。
【解决方案2】:

击落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;

【讨论】:

  • 我觉得Foo类要大很多,作者尽量避免手动反序列化
  • 是的,真正的 XML 和类结构是巨大的!重构所有内容以使用 Linq2Xml 将是一项艰巨的工作。
猜你喜欢
  • 2012-05-29
  • 2020-05-31
  • 2021-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-08
  • 1970-01-01
  • 2014-11-30
相关资源
最近更新 更多