web-dev-qa-db-ja.com

XMLシリアル化中はプロパティを無視しますが、逆シリアル化中は無視しません

C#で、シリアル化中にXmlSerializerがプロパティを無視するようにするにはどうすればよいですか? (または、Json.netで同じことを行うにはどうすればよいですか?)

プロパティがシリアル化されないようにするには、XmlIgnore属性を追加できます。

[XmlIgnore]
public int FooBar {get;set;}

これにより、<FooBar>タグは、シリアル化中に省略されます。

ただし、これは、<FooBar>タグは、逆シリアル化中に無視されます。

私の場合、リクエストでユーザーからのアイテムの配列を受け入れます。アイテムを追加、変更、または削除する場合、ユーザーはアイテムごとにアクションプロパティを指定できます。 GETリストの呼び出しに同じモデルオブジェクトを使用したいのですが、このアクションプロパティを返したくありません。これはかなり一般的なケースになると思います。

別のユースケース:サークルオブジェクトがあるとします

public class Circle
{
    public double Radius { get; set; }
}

直径プロパティを追加するように変更します

public class Circle2
{
    public double Diameter { get; set; }
    public double Radius { get { return Diameter / 2; } set { Diameter = value*2; } }
}

直径のみをシリアル化することもできますが、それでも半径のみを含む古い形式のxmlファイルを逆シリアル化することができます。

私は自分の研究をして何も見つけられなかったので、この質問

Solution:解決策を見つけました。常にfalseを返すShouldSerializeプロパティを追加できます。詳細は このMSDNドキュメント

(この質問が再び開かれた場合、このソリューションを実際の回答として追加できます)

46
Manoj

XmlSerializerでのシリアル化で要素を無視する場合は、XmlAttributeOverridesを使用できます。

XmlAttributeOverrides overrides = new XmlAttributeOverrides();
XmlAttributes attribs = new XmlAttributes();
attribs.XmlIgnore = true;
attribs.XmlElements.Add(new XmlElementAttribute("YourElementName"));
overrides.Add(typeof(YourClass), "YourElementName", attribs);

XmlSerializer ser = new XmlSerializer(typeof(YourClass), overrides);
ser.Serialize(...
29
fcuesta

これは、Manojが概説したソリューションです。

特定のプロパティFooのシリアル化を抑制したいが、それでも逆シリアル化できる場合は、常にfalseを返すメソッドpublic bool ShouldSerializeFoo()を追加できます。

例:

public class Circle2
{
    public double Diameter { get; set; }
    public double Radius { get { return Diameter / 2; } set { Diameter = value*2; } }

    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
    public bool ShouldSerializeRadius() {return false;}
}

これにより、Radiusのシリアル化は行われませんが、逆シリアル化は可能です。

このメソッドは、XMLSerializerがそれを見つけるためにパブリックである必要があるため、名前空間の汚染を避けるために、EditorBrowsable属性を追加してIDEから非表示にすることができます。残念ながら、この非表示は、アセンブリが現在のプロジェクトでDLLとして参照されている場合にのみ機能しますが、このコードで実際のプロジェクトを編集する場合には機能しません。

31
HugoRune