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

限于喜欢 提交于 2019-12-17 15:59:14

问题


I am trying to figure out how to serialize/deserialize an XML listing to C# that has an optional attribute that is an enumerated type. The following is my C# class:

public class AttributeAssignmentExpressionElement : XACMLElement
{
    [XmlAttribute]
    public string AttributeId { get; set; }

    [XmlAttribute]
    public Category Category { get; set; }                   
}

My Category enumeration is defined as follows:

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
}  

When Category is present in the corresponding XML file, serialization/deserialization works as expected. However if the Category is missing from the XML, the default value is used (first item in the enumeration). If I try to make the enumerated variable nullable (Category?), the deserializer throws an exception because it is unable to deserialize a complex type. Given the following XML (which does not contain the attribute), how can I serialize the enumeration appropriately?

<AttributeAssignmentExpression
    AttributeId="urn:oasis:names:tc:xacml:3.0:example:attribute:text">       
</AttributeAssignmentExpression>

In this situation, the value in the deserialized object should be null.

Thanks for any help you can offer!


回答1:


Well, you can do this - but it is a bit messy:

[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;
}

What this does:

  • uses a Category? for the optional enum value
  • disables the Category property for serialization
  • adds a secondary property, CategorySerialized, as a proxy to Category, which is non-nullable and hidden (as far as is possible) from the IDE etc
  • use conditional serialization on CategorySerialized via the ShouldSerialize* pattern



回答2:


Actually, there's some official magic which allows to do this (see here):

Another option is to use a special pattern to create a Boolean field recognized by the XmlSerializer, and to apply the XmlIgnoreAttribute to the field. The pattern is created in the form of propertyNameSpecified. For example, if there is a field named "MyFirstName" you would also create a field named "MyFirstNameSpecified" that instructs the XmlSerializer whether to generate the XML element named "MyFirstName". This is shown in the following example.

That is, the model in TS case should look like this:

public class AttributeAssignmentExpressionElement : XACMLElement
{
    [XmlAttribute]
    public string AttributeId { get; set; }

    [XmlAttribute]
    public Category Category { get; set; }

    [XmlIgnore]
    public bool CategorySpecified { get; set; }                   
}

Unless you set magic field CategorySpecified to true, Category attribute won't be serialized. In case of deserialization, CategorySpecified will be false, indicating that Category wasn't present in XML.




回答3:


The complete sample code using 'Specified' pattern

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;

}


来源:https://stackoverflow.com/questions/10840197/how-to-serialize-deserialize-optional-xml-enumeration-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!