次のサンプル wcf サービスがあります (webHttpBinding を使用):
[ServiceContract]
public class Animals {
[OperationContract]
[WebGet(UriTemplate = "/{id}")]
[ServiceKnownType(typeof(Dog))]
public Animal GetAnimalById(string id) {
switch (id) {
case "1": return new Animal { Id = 1 };
case "2": return new Dog { Id = 2 };
}
throw new ArgumentException();
}
}
タイプは次のように定義されます。
[DataContract]
[KnownType(typeof(Dog))]
public class Animal {
[DataMember]
public int Id { get; set; }
}
public class Dog : Animal {
[DataMember]
public string Name { get; set; }
}
1 が指定された場合、サービスから返される xml は次のとおりです (簡潔にするために xmlns は省略されています)。
<Animal><Id>1</Id><Name i:nil="true"/></Animal>
2 を指定した場合:
<Dog><Id>2</Id><Name i:nil="true"/></Dog>
そして、ここに質問があります: Animal 用に構築された DataContractSerializer が 2 番目の xml を逆シリアル化できないのはなぜですか? 次のようなものをスローします: 名前空間 'bla bla' から要素 'Animal' を期待しています.. 名前 'Dog'、名前空間 'bla bla' の 'Element' に遭遇しました。
追加情報:
1. typeof(Dog) をパラメーターとして指定する DataContractSerializer を構築すると、明らかに機能します。
2. typeof(Animal) をパラメーターとして提供する DataContractSerializer を構築し (シリアライズ/デシリアライズしようとしているオブジェクトのタイプがわからないため)、Dog をシリアライズすると、xml は次のようになります。
<Animal i:type="Dog"><Id>0</Id><Name i:nil="true"/></Animal>
これは、同じシリアライザーを使用して問題なく逆シリアル化できます。派生型ではなく基本型で提供される DataContractSerializer を使用して WCF を強制的にシリアル化することはできますか?