繁体   English   中英

如何在C#中序列化/反序列化可选XML枚举?

[英]How to serialize/deserialize optional XML enumeration in C#?

我试图弄清楚如何将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。

谢谢你的尽心帮助!

好吧,您可以执行此操作-但这有点混乱:

[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等,这是不可为空和隐藏(只要有可能)
  • 通过ShouldSerialize*模式对CategorySerialized使用条件序列化

实际上,有一些官方魔术可以做到这一点( 请参阅此处 ):

另一个选择是使用特殊的模式来创建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

使用“指定”模式的完整示例代码

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;

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM