次のシナリオでは、クライアント側でシリアル化の問題が発生しています。
サービスコードに次のクラスとメソッドがあるとしましょう
[DataContract]
public class Derived
{
[DataMember]
public string A { get; set; }
[DataMember]
public string B { get; set; }
[DataMember]
public string C { get; set; }
[DataMember]
public string D { get; set; }
}
サービスインターフェイスにはメソッドがあります
[OperationContract]
Derived GetDerived();
メソッドの実装 -
public Derived GetDerived()
{
var d = new Derived() {A = "A", B = "B", C = "C", D = "D"};
return d;
}
この WCF サービスでは、(サービス参照を追加して) クライアント プロキシを作成し、GetDerived() 呼び出しを実行すると、すべて正常に動作します。
サービスコードのエンティティを少し変更しましょう
[DataContract]
public class Base
{
[DataMember]
public string B { get; set; }
}
[DataContract]
public class Derived : Base
{
[DataMember]
public string A { get; set; }
[DataMember]
public string C { get; set; }
[DataMember]
public string D { get; set; }
}
この場合、新しい基本クラスを作成し、プロパティ「B」を基本クラスに移動しました。クライアント側で同じ古いプロキシを使用して、GetDerived 呼び出しを行うと、クライアント側で適切にシリアル化された A の値が表示されません。ただし、旧バージョンと現バージョンの SOAP メッセージは同じです (順序のみが変更されています)。このhttp://msdn.microsoft.com/en-us/library/ms729813.aspxの記事に出くわし、順序について説明しました。「B」を基本クラスに移動したため、派生クラスでの順序を制御する方法がわかりません。
この問題の回避策はありますか? これにより、クライアントへの下位互換性が失われます。
一方、新しいプロパティを追加すると、たとえば C1 を派生クラス (または既存のクラス) に追加すると、順序も変更されます。これがクライアントを壊さないのはなぜですか?先ほど述べたシナリオとは異なります。