2010-08-26 31 views
7

Tôi có một lớp cơ sở với các thuộc tính DataMember trong đó. Tôi cũng có một lớp dẫn xuất với các thuộc tính DataMember trong đó. Trong dự án WCF của tôi, tôi đang quay trở lại lớp dẫn xuất. Có cách nào để tôi ngăn cản một thành viên trong lớp cơ sở của tôi từ tuần tự hóa không? Dưới đây là một số mã mẫu:WCF DataContract Loại trừ DataMembers Từ Đang tuần tự hóa trong các lớp có nguồn gốc

public class BaseClass 
{ 
    public string ShortDescription {get;set;} 
    public string LongDescription {get;set;} 
} 

public class DerivedClass : BaseClass 
{ 
    public List<Description> Descriptions {get;set;} 
} 

Trong mã này tôi muốn có thể ẩn thành viên được thừa kế ShortDescription và LongDescription vì chúng đã lỗi thời. Mọi nỗ lực làm như vậy đều không thành công. Dưới đây là những gì tôi đã cố gắng:

public class DerivedClass : BaseClass 
{ 
    [DataMember] 
    public List<Description> Descriptions {get;set;} 

    // override the base class members 
    [IgnoreDataMember]  
    public override string ShortDescription {get;set;} 
    [IgnoreDataMember] 
    public override string LongDescription {get;set;} 
} 

public class DerivedClass : BaseClass 
{ 
    [DataMember] 
    public List<Description> Descriptions {get;set;} 

    // shadow the base class members 
    [IgnoreDataMember]  
    public new string ShortDescription {get;set;} 
    [IgnoreDataMember] 
    public new string LongDescription {get;set;} 
} 

Không phải của các phương pháp đã làm việc. Loại "DerivedClass" khi đầu ra cho WSDL vẫn chứa các thành viên "Bỏ qua" của loại lớp cơ sở.

Bạn có thể thắc mắc tại sao tôi không chỉ thay đổi lớp cơ sở. Điều này là do tôi vẫn sử dụng lớp cơ sở ở dạng ban đầu của nó làm phiên bản trước của loại cho WSDL để hỗ trợ khả năng tương thích ngược cho người tiêu dùng. Bằng cách này tôi có thể có một cuộc gọi v1000 trả về BaseClass và một cuộc gọi V1010 trả về một DerivedClass. Tôi có thể thêm và thay đổi chức năng cho DerivedClass tất cả những gì tôi muốn mà không có khả năng ảnh hưởng đến người tiêu dùng của chức năng v1000.

Trả lời

2

Cuối cùng tôi đã tìm thấy một cách phù hợp để xử lý tác vụ này. Tôi không có mã ở trước mặt nên tôi sẽ viết cú pháp. Đó là một giải pháp khá đơn giản, nhưng nó giải quyết được vấn đề cụ thể mà tôi gặp phải.

public class BaseClass 
{ 
    // leave this guy empty 
} 

public class DerivedClassVersion1 : BaseClass 
{ 
    [DataMember] 
    public string ShortDescription {get;set;} 

    [DataMember] 
    public string LongDescription {get;set;} 
} 

public class DerivedClassVersion2 : BaseClass 
{ 
    [DataMember] 
    public List<Description> Descriptions {get;set;} 
} 

Badda bing! Khá đơn giản, nhưng đó là những gì tôi cần.

0

Hãy thử điều này:

public class BaseClass 
{ 
    [DataMember] 
    public virtual string ShortDescription {get;set;} 

    [DataMember] 
    public virtual string LongDescription {get;set;} 
} 

public class DerivedClass : BaseClass 
{ 
    [DataMember] 
    public List<Description> Descriptions {get;set;} 

    public override string ShortDescription {get;set;} 
    public override string LongDescription {get;set;} 
} 

EDIT: Có lẽ việc sử dụng hợp đồng nhắn để kiểm soát chính xác serialization có thể làm việc: http://msdn.microsoft.com/en-us/library/ms730255.aspx

Nếu không, bạn cũng có thể nhìn vào thực hiện một 'WCF Router' mà sẽ cho phép bạn để sử dụng cùng điểm cuối, nhưng định tuyến các phiên bản khác nhau cho các dịch vụ khác nhau.

+1

Điều này tạo ra kết quả tương tự. Thật thú vị nếu tôi ghi đè lên và cung cấp thuộc tính [DataMember] trong một nỗ lực để nó hiển thị trong định nghĩa XML cho DerivedClass nó vẫn không hiển thị trong DerivedClass nhưng trong lớp cơ sở. – omatase

+0

Hrmmpf ... yep, không hoạt động;) – Kwal

6

Thử thêm thuộc tính [DataContract] vào cả hai lớp. Điều này sẽ cho trình serializer xem xét các thuộc tính [DataMember] và [IgnoreDataMember]. Nếu không có lớp được gán cho [DataContract], tất cả các thành viên công cộng sẽ được tuần tự hóa.

[DataContract] 
public class BaseClass 
{ 
    [IgnoreDataMember] 
    public string ShortDescription {get;set;} 

    [IgnoreDataMember] 
    public string LongDescription {get;set;} 
} 

[DataContract] 
public class DerivedClass : BaseClass 
{ 
    [DataMember] 
    public List<Description> Descriptions {get;set;} 
} 

Ngoài ra, tốt hơn nên thêm không gian tên vào dữ liệu địa lý của bạn bằng cách chỉ định nó trong thuộc tính [DataContract (Namespace = "...")]. Điều đó sẽ phá vỡ các khách hàng cũ gọi dịch vụ cập nhật của bạn.

+0

Đáng chú ý rằng WITH [DataContract] trên lớp bạn không còn cần đến trình khám phá [IgnorDataMember] nữa - vì chỉ các thành viên có [DataMember] mới được đưa vào vận chuyển. – Ricibob

Các vấn đề liên quan