1. ホーム
  2. c#

[解決済み] XmlInclude または SoapInclude 属性を使用して、静的に知られていない型を指定します。

2022-10-15 21:48:45

質問

.NETの XmlSerializer .

次のようなクラス例を考えてみましょう。

public class Order 
{
    public PaymentCollection Payments { get; set; }

    //everything else is serializable (including other collections of non-abstract types)
}

public class PaymentCollection : Collection<Payment>
{
}

public abstract class Payment 
{
    //abstract methods
}

public class BankPayment : Payment
{
    //method implementations
}

を解決する方法は3種類あります。 InvalidOperationException の派生型についてシリアライザが知らないことが原因です。 Payment .

1. 追加する XmlIncludePayment クラス定義に追加します。

これは、すべてのクラスが、私がコントロールできない外部参照として含まれているため、不可能です。

2. の生成時に派生型の型を渡す。 XmlSerializer インスタンス

動作しない。

3. 定義する XmlAttributeOverrides で説明したように)プロパティのデフォルトのシリアライズを上書きするために、ターゲットプロパティに このSOポスト )

もうまくいきません( XmlAttributeOverrides の初期化が続く)。

Type bankPayment = typeof(BankPayment);

XmlAttributes attributes = new XmlAttributes();
attributes.XmlElements.Add(new XmlElementAttribute(bankPayment.Name, bankPayment));

XmlAttributeOverrides overrides = new XmlAttributeOverrides();
overrides.Add(typeof(Order), "Payments", attributes);

適切な XmlSerializer のコンストラクタが使用されるでしょう。

は動作しません。 というのは InvalidOperationException ( BankPayment は想定外でした...。 が投げられます。

どなたか、この問題に光を当てていただけませんか。どのようにして、この問題をさらにデバッグするのでしょうか。

どのように解決するのでしょうか。

ちょうど問題を解決しました。もうしばらく探し回って、見つけたのは このSOの投稿 を見つけました。これは、私を正しい道に導いてくれました。

基本的には XmlSerializer はデフォルトの名前空間である もし の派生クラスが追加型として含まれる場合、デフォルトの名前空間を知る必要があります。なぜこのようなことが起こるのか、正確な理由はまだ不明ですが、それでもシリアライズは現在動作しています。