如果空的枚举列表在xmlattribute中,则C#XmlSerializer会在反序列化空枚举列表时失败 [英] C# XmlSerializer fails on deserialization of an empty enum list if it's in an xmlattribute
问题描述
这是对我未来自我的记录,也是对他人有益的记录. 所描述的行为并不明显...
This is a note to my future self, and for the benefit of others. The described behavoir is NOT obvious...
我有一些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,则会得到:
If I use the XmlSerializer to serialize this to xml I get:
(请注意最后的空AllowedChoices属性)
( Note the empty AllowedChoices attribute at the end )
<?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反序列化,则类似于:
If I then use the XmlSerializer to deserialize this xml I something like:
System.InvalidOperationException : There is an error in XML document (2, 109).
----> System.InvalidOperationException : Instance validation error: '' is not a valid value for Choices.
这是一个空的列表枚举,可以无错误地序列化,是的,请不要反序列化!
This is an empty list of enums that serializes without error, Y U NO deserialize!?
推荐答案
我发现了以下相关问题,这些问题由于预期的原因而失败,即枚举不具有空默认值,这是一个提示...
I've found these related questions, which fail for expected reasons, namely that an enum does not have a null default value, which is a clue...
XmlSerializer枚举反序列化在(不存在)空白上失败
这是解决方案:
如果AllowedChoices的实现是自动属性,并且未在构造函数中初始化(即当反序列化到达该属性时为空),则它将按预期工作,并且不会在反序列化时爆炸.
If the implementation of AllowedChoices is an auto-property and is not initialized in the constructor (i.e. it's null when deserialization gets to that property) it works as expected, and does not bomb on deserialization.
我对源代码拥有完全的控制权,所以我要务实的是,使用[XmlEnum(")]属性将None值添加到我的Choices枚举中,如果唯一的值是空白,则将列表视为空而不是 not 进行列表的自动初始化.
I have full control over the source, so I'm going to be pragmatic and add an None value to my Choices enum with a [XmlEnum("")] attribute, and treat the list as empty if that's the only value in the list instead of not doing auto-initialization of the list.
请参见 http://tech.pro/blog/1370/why-collections-should-ever-never-null-null (为什么我想要那样).
See http://tech.pro/blog/1370/why-collections-should-never-be-null for why I want that.
奖金提示:
如果要创建枚举别名的空字符串,请执行以下操作:
If you want to create an empty-string of an enum alias do it like this:
public enum Choices
{
[XmlEnum("default")]
Default = 0,
[XmlEnum("")]
DefaultAlias = Default,
}
这篇关于如果空的枚举列表在xmlattribute中,则C#XmlSerializer会在反序列化空枚举列表时失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!