【问题标题】:C# XmlSerializer fails on deserialization of an empty enum list if it's in an xmlattribute如果空枚举列表位于 xmlattribute 中,则 C# XmlSerializer 在反序列化空枚举列表时失败
【发布时间】:2014-02-19 10:44:12
【问题描述】:

这是给我未来的自己的便条,也是为了他人的利益。 所描述的行为并不明显......

我有一点 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.

这是一个空的 list 枚举,可以无错误地序列化,Y U NO 反序列化!?

【问题讨论】:

    标签: c# enums attributes xmlserializer


    【解决方案1】:

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

    deserializing enums

    XmlSerializer enumeration deserialization failing on (non existent) whitespace

    这就是解决方案:

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

    我可以完全控制源,所以我会务实地使用 [XmlEnum("")] 属性将 None 值添加到我的 Choices 枚举中,如果这是唯一的值,则将列表视为空在列表中而不是对列表进行自动初始化。

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

    额外提示:

    如果你想创建一个枚举别名的空字符串,可以这样做:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-16
      • 1970-01-01
      • 2019-05-31
      相关资源
      最近更新 更多