如果它在xmlattribute中,则C#XmlSerializer在对空枚举列表进行反序列化时失败

时间:2014-02-19 10:44:12

标签: c# enums attributes xmlserializer

这是对我未来的自我,并为了他人的利益。 描述的行为并不明显......

我有一点C#:

public enum Choices 
{
  One,
  Two,
  Three,
}

public class Element 
{
  List<Choices> _allowedChoices;
  [XmlAttribute]
  public List<Choices> AllowedChoices
  {
    get {return _allowedChoices ?? ( _allowedChoices = new List<Choices>() );}
    set { _allowedChoices = value; }
  }
}

[Test]
public void testing_empty_enum_list_serialization()
{
    var ser = new XmlSerializer(typeof (Element));
    using (var sw = new StringWriter())
    {
        ser.Serialize(sw, new Element
        {
            AllowedChoices = {},
        });
        var text = sw.ToString();
        Console.WriteLine(text);
        using (var sr = new StringReader(text))
        {
            var deserialized  = (Element) ser.Deserialize(sr);
        }
    }
}

如果我使用XmlSerializer将其序列化为xml,我得到:

(注意末尾的空AllowedChoices属性)

<?xml version="1.0" encoding="utf-16"?>
<Element xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" AllowedChoices="" />

如果我然后使用XmlSerializer反序列化这个xml,我会像:

System.InvalidOperationException : There is an error in XML document (2, 109).
  ----> System.InvalidOperationException : Instance validation error: '' is not a valid value for Choices.

这是一个空的列表的枚举序列,没有错误,Y U NO反序列化!?

1 个答案:

答案 0 :(得分:1)

我发现了这些相关问题,这些问题因预期原因而失败,即枚举没有默认值,这是一个线索......

deserializing enums

XmlSerializer enumeration deserialization failing on (non existent) whitespace

这就是解决方案:

如果AllowedChoices的实现是一个自动属性并且未在构造函数中初始化(即当反序列化到达该属性时它为null ),它按预期工作,并且不会在反序列化时爆炸。

我可以完全控制源代码,因此我将实用并使用[XmlEnum(“”)]属性向我的Choices枚举中添加None值,如果这是唯一值,则将列表视为空在列表中而不是进行列表的自动初始化。

请参阅http://tech.pro/blog/1370/why-collections-should-never-be-null我想要的原因。

奖金提示:

如果要创建枚举别名的空字符串,请执行以下操作:

public enum Choices
{
    [XmlEnum("default")]
    Default = 0,

    [XmlEnum("")]
    DefaultAlias = Default,
}