2011-12-18 42 views
20

Làm thế nào để sử dụng DataContract với kế thừa? Mã dưới đây có hoạt động không?DataContract và thừa kế?

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

} 

[DataContract] 
public class SomeData : ConsoleData 
{ 

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

Có. Bạn đang cố gắng làm gì với hai hợp đồng dữ liệu đó? –

Trả lời

34

Vâng, đó sẽ làm việc.

DataContractAttributeInherited đặt thành false, vì vậy cần áp dụng thuộc tính cho cả lớp con và lớp cha mẹ (như bạn đã làm trong câu hỏi).


Bạn cần sử dụng thuộc tính KnownType nếu bạn muốn sử dụng hợp đồng dữ liệu của mình với đa hình.

Ví dụ

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

Nếu bạn gọi phương pháp như vậy:

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); 

Sau đó deserializer vào cuối vụ sẽ không biết rằng đó là một thể hiện của SomeData, chỉ một thể hiện của ConsoleData mà nó đang mong đợi. Cách khắc phục điều này là đăng ký lớp SomeData dưới dạng kiểu đã biết của ConsoleData.

+0

cảm ơn, thực sự giúp đỡ và cố định các vấn đề của tôi – javapowered

+0

@Andrew. Tôi đang đấu tranh với những chủ đề này một thời gian dài. Có thể có trong '[OperationContract] HandleData (Base base);' và gửi từ SoapUI một số đối tượng đã được lấy từ 'Base'? Và sau đó nếu C# sẽ nhận thức được thực tế rằng trên 'cơ sở', nó giữ trường hợp của một số phân lớp - vì vậy nó gọi các phương thức thích hợp (đa hình và vân vân) –

+0

Có một lỗi cú pháp nhỏ trong [KnownType (typeof (SomeData)) ], cảm ơn vì bài đăng hữu ích. – Shanjee

2

Bạn sẽ cần phải sử dụng thuộc tính KnownType nếu bạn đang sử dụng XmlSerializerFormat cho ServiceContract của bạn:

[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

điều gì sẽ không hoạt động nếu không có 'KnownType'? Tôi đã thử mã như tôi đã viết trong mô tả và nó có vẻ làm việc – javapowered

+1

Tôi câu hỏi này. Có nghĩa là đặt KnownType (typeof (SomeData)) vào lớp cơ sở (ConsoleData), cho phép bạn truyền một thể hiện con cho một phương thức mong đợi một cá thể cơ sở. Nhưng tôi không nghĩ rằng bạn cần phải đặt nó vào ví dụ con. –

+0

@javapowered: Chỉ cần cẩn thận nếu bạn quyết định không sử dụng thuộc tính KnownType vì có những trường hợp đặc biệt cần thiết. Một ví dụ như vậy là nếu bạn đã để lộ SomeData như một tài sản của một DataContract khác. –