2011-12-18 105 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

是的。你想用這兩個數據合約做什麼? – 2011-12-18 21:58:12

回答

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類註冊爲已知類型的ConsoleData

+0

謝謝,真的幫助和解決我的問題 – javapowered 2011-12-18 23:19:22

+0

@Andrew。很長一段時間我對這些主題很感興趣。是否可以在'[OperationContract] HandleData(Base base);'中並且從SoapUI發送一些來自'Base'的緩存對象?然後,如果c#將會意識到在'base'上它保存了某個子類的實例 - 因此它也調用適當的方法(多態性等) – 2017-04-06 08:39:00

+0

[KnownType(typeof(SomeData))中存在小的語法錯誤],謝謝你的帖子。 – Shanjee 2018-01-09 09:33:37

2

你需要,如果你使用的是XmlSerializerFormat您的ServiceContract使用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 2011-12-18 21:59:30

+1

我質疑這一點。將KnownType(typeof(SomeData))放在基類(ConsoleData)上是有意義的,允許您將子實例傳遞給期望基實例的方法。但我認爲你不需要把它放在子實例上。 – 2011-12-18 22:02:40

+0

@javapowered:如果您決定不使用KnownType屬性,請注意,因爲有特殊情況需要它。一個這樣的例子是,如果您要將SomeData作爲另一個DataContract的屬性公開。 – 2011-12-18 22:03:29