2011-12-18 10 views
20

継承でDataContractを使用するにはどうすればいいですか?以下のコードは機能しますか?DataContractと継承?

[DataContract] 
public class ConsoleData 
{ 
    [DataMember] 
    public String Description { get; set; } 

} 

[DataContract] 
public class SomeData : ConsoleData 
{ 

    [DataMember] 
    public int Volume { get; set; } 
    ...... 
+0

はい。あなたはこれら2つのデータ契約で何をしようとしていますか? –

答えて

34

はい、それは動作します。

DataContractAttributeInheritedがfalseに設定されているため、(この質問で行ったように)子クラスと親クラスの両方に属性を適用する必要があります。


多態性を持つデータコントラクトを使用する場合は、 KnownType属性を使用する必要があります。

あなたがそうのようなメソッドを呼び出した場合

[ServiceContract] 
interface MyWcfContract 
{ 
     [OperationContract] 
     HandleData(ConsoleData contractData); 
} 

例えば:

SomeData someData = new SomeData { Description = "Test", Volume = 30 }; 
// The method is expecting a ConsoleData instance, 
// I'm passing a SomeData instance instead 
myWcfProxy.HandleData(someData); 

そして、サービス側のデシリアライザは、それがSomeDataのインスタンスだとConsoleDataのインスタンスだけを知ることができませんそれは期待していた。 これを解決する方法は、の既知のタイプとしてSomeDataクラスを登録することです。

+0

ありがとう、本当に助けられて私の問題が解決されました – javapowered

+0

@Andrew。私はこれらの主題で長い間戦っています。 '[OperationContract] HandleData(Base base);を持ち、SoapUIからいくつかのオブジェクトを' Base'から送信することは可能ですか?そして、もしc#が 'base'でいくつかのサブクラスのインスタンスを保持していることを知っているなら - 適切なメソッドも呼び出す(多態性など) –

+0

[KnownType(typeof(SomeData))に小さな構文エラーがありました]、役立つポストに感謝します。 – Shanjee

2

あなたは、あなたのServiceContractためXmlSerializerFormatを使用している場合KnownType属性を使用する必要があります:

[DataContract] 
public class ConsoleData 
{ 
    [DataMember] 
    public String Description { get; set; } 
} 

[DataContract, KnownType(typeof(ConsoleData))] 
public class SomeData : ConsoleData 
{ 
    [DataMember] 
    public int Volume { get; set; } 
} 
+0

'KnownType'なしでは何ができませんか?私は記述で書いたようにコードを試しましたが、それはうまくいくようです – javapowered

+1

私はこれに質問します。 KnownType(typeof(SomeData))を基本クラス(ConsoleData)に配置すると、基本インスタンスが必要なメソッドに子インスタンスを渡すことができます。しかし、私はあなたが子供のインスタンスに配置する必要はないと思う。 –

+0

@ javapowered:必要な特殊なケースがあるため、KnownType属性を使用しないことに決めたら、注意してください。そのような例の1つは、SomeDataをさらに別のDataContractのプロパティとして公開する場合です。 –