7

列挙型であるオプションの属性を持つC#にXMLリストをシリアル化/逆シリアル化する方法を理解しようとしています。以下は私の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、シリアル化/逆シリアル化は期待どおりに機能します。ただしCategory、XMLにが欠落している場合は、デフォルト値が使用されます(列挙の最初の項目)。列挙型をnull許容()にしようとするとCategory?、複合型を逆シリアル化できないため、デシリアライザーは例外をスローします。次のXML(属性を含まない)がある場合、列挙を適切にシリアル化するにはどうすればよいですか?

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

この状況では、逆シリアル化されたオブジェクトの値はnullである必要があります。

あなたが提供できるどんな助けにも感謝します!

4

3 に答える 3

14

まあ、あなたはこれを行うことができます-しかしそれは少し厄介です:

[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?オプションの列挙値にaを使用します
  • Categoryシリアル化のプロパティを無効にします
  • CategorySerializedプロキシとしてセカンダリプロパティを追加しますCategory。これはnull許容ではなく、IDEなどから(可能な限り)非表示になります。
  • パターンをCategorySerialized介して条件付きシリアル化を使用するShouldSerialize*
于 2012-05-31T20:12:03.043 に答える
4

実際、これを可能にするいくつかの公式の魔法があります(ここを参照):

別のオプションは、特別なパターンを使用してXmlSerializerによって認識されるブールフィールドを作成し、XmlIgnoreAttributeをフィールドに適用することです。パターンはpropertyNameSpecifiedの形式で作成されます。たとえば、「MyFirstName」という名前のフィールドがある場合は、「MyFirstName」という名前のXML要素を生成するかどうかをXmlSerializerに指示する「MyFirstNameSpecified」という名前のフィールドも作成します。これを次の例に示します。

つまり、TSの場合のモデルは次のようになります。

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

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

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

マジックフィールドCategorySpecifiedをに設定しない限りtrueCategory属性はシリアル化されません。デシリアライズの場合、は、XMLに存在しなかったCategorySpecifiedことfalseを示します。Category

于 2013-12-01T19:42:30.417 に答える
3

「指定された」パターンを使用した完全なサンプルコード

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;

}
于 2017-08-15T17:19:34.850 に答える