我试图弄清楚如何将XML列表序列化/反序列化为C#,它具有枚举类型的可选属性。以下是我的C#类:
public class AttributeAssignmentExpressionElement : XACMLElement
{
[XmlAttribute]
public string AttributeId { get; set; }
[XmlAttribute]
public Category Category { get; set; }
}
我的Category
枚举定义如下:
public enum Category
{
[XmlEnum(Name = "urn:oasis:names:tc:xacml:1.0:subject-category:access-subject")]
Subject,
[XmlEnum(Name = "urn:oasis:names:tc:xacml:3.0:attribute-category:resource")]
Resource,
[XmlEnum(Name = "urn:oasis:names:tc:xacml:3.0:attribute-category:action")]
Action,
[XmlEnum(Name = "urn:oasis:names:tc:xacml:3.0:attribute-category:environment")]
Environment
}
当相应的XML文件中存在Category
时,序列化/反序列化按预期工作。但是,如果XML中缺少Category
,则使用默认值(枚举中的第一项)。如果我尝试使枚举变量为空(Category?
),则反序列化器会抛出异常,因为它无法反序列化复杂类型。给定以下XML(不包含该属性),如何正确地序列化枚举?
<AttributeAssignmentExpression
AttributeId="urn:oasis:names:tc:xacml:3.0:example:attribute:text">
</AttributeAssignmentExpression>
在这种情况下,反序列化对象中的值应为null。
感谢您提供的任何帮助!
答案 0 :(得分:13)
嗯,你可以这样做 - 但它有点乱:
[XmlIgnore]
public Category? Category { get; set; }
[XmlAttribute("Category")]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public Category CategorySerialized
{
get { return Category.Value; }
set { Category = value; }
}
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public bool ShouldSerializeCategorySerialized()
{
return Category.HasValue;
}
这是做什么的:
Category?
作为可选的枚举值Category
属性CategorySerialized
添加为Category
的代理,该代理不可空,并且(尽可能隐藏)来自IDE等CategorySerialized
模式ShouldSerialize*
上使用条件序列化
答案 1 :(得分:4)
实际上,有一些官方魔术允许这样做(see here):
另一种选择是使用特殊模式创建XmlSerializer可识别的布尔字段,并将XmlIgnoreAttribute应用于该字段。该模式以propertyNameSpecified的形式创建。例如,如果有一个名为“MyFirstName”的字段,您还将创建一个名为“MyFirstNameSpecified”的字段,该字段指示XmlSerializer是否生成名为“MyFirstName”的XML元素。这在以下示例中显示。
也就是说,TS案例中的模型应如下所示:
public class AttributeAssignmentExpressionElement : XACMLElement
{
[XmlAttribute]
public string AttributeId { get; set; }
[XmlAttribute]
public Category Category { get; set; }
[XmlIgnore]
public bool CategorySpecified { get; set; }
}
除非您将魔术字段CategorySpecified
设置为true
,否则Category
属性将不会被序列化。如果是反序列化,CategorySpecified
将为false
,表示XML中不存在Category
。
答案 2 :(得分:1)
完整的示例代码使用&#39;指定&#39;图案
public class ClassToSerialize
{
[XmlAttribute("attributeName")]
public EnumType EnumPropertyValue
{
get { return EnumProperty.Value; }
set { EnumProperty = value; }
}
[XmlIgnore]
public EnumType? EnumProperty { get; set; }
public bool EnumPropertyValueSpecified => EnumProperty.HasValue;
}