Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C#中序列化/反序列化可选XML枚举?_C#_Xml_Xml Serialization - Fatal编程技术网

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

如何在C#中序列化/反序列化可选XML枚举?,c#,xml,xml-serialization,C#,Xml,Xml Serialization,我试图弄清楚如何将XML列表序列化/反序列化为C#,该C#具有枚举类型的可选属性。以下是我的C#类: 我的类别枚举定义如下: 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-catego

我试图弄清楚如何将XML列表序列化/反序列化为C#,该C#具有枚举类型的可选属性。以下是我的C#类:

我的
类别
枚举定义如下:

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中缺少
类别
,则使用默认值(枚举中的第一项)。如果我试图使枚举变量为null(
类别?
),反序列化程序将抛出异常,因为它无法反序列化复杂类型。给定以下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;
}
它的作用是:

  • 使用
    类别?
    作为可选枚举值
  • 禁用用于序列化的
    类别
    属性
  • 添加一个辅助属性,
    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; }                   
}

除非将magic field
categorysspecified
设置为
true
Category
属性将不会序列化。在反序列化的情况下,
categorysspecified
将为
false
,表明
Category
在XML中不存在。

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

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;

}

如果从模式开始(我推荐),这与xsd编写的内容非常接近,只是实际值不需要单独的属性。实际上,我使用XmlIgnore属性实现了一些与之相当的东西。我希望有一种更干净的方法。看来这是唯一的办法。谢谢
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;

}