2008-11-19 49 views
50

VS.net tạo mẫu khi bạn tạo dự án WCF.Điểm của DataContract trong WCF là gì?

Nó cho biết thêm một lớp học để các tập tin iService1.cs:

// Use a data contract as illustrated in the sample below to 
// add composite types to service operations. 
[DataContract] 
public class CompositeType 
{ 
    bool boolValue = true; 
    string stringValue = "Hello "; 

    [DataMember] 
    public bool BoolValue 
    { 
     get { return boolValue; } 
     set { boolValue = value; } 
    } 

    [DataMember] 
    public string StringValue 
    { 
     get { return stringValue; } 
     set { stringValue = value; } 
    } 
} 

Kể từ khi một dịch vụ WCF có thể trả lại bất kỳ người dùng định nghĩa lớp, tại sao sử dụng một lớp DataContract và CompositeType?

tôi có thể trở lại một cái gì đó như:

[OperationContract] 
MyUserCollection GetUsers(); 

tôi đang thiếu gì?

+19

Nếu bạn có NET trên cả hai đầu của dây, đó là tốt. Nếu bạn có một khách hàng Java gọi dịch vụ của bạn thì sao? Nếu bạn đặt dữ liệu của bạn bên trong DataContracts, thông tin đó được lưu trữ trong siêu dữ liệu WSDL/XSD và có thể được sử dụng bởi các máy khách khác với .NET. –

Trả lời

51

DataContract chỉ là định nghĩa chính thức của một loại có thể được hiểu trên cả hai mặt của ranh giới dịch vụ.

Nếu bạn quay trở lại, như trong ví dụ của bạn, đối tượng "MyUserCollection", người tiêu dùng dịch vụ của bạn sẽ cần tham chiếu đến nội bộ dịch vụ/hệ thống của bạn, vi phạm nguyên lý SOA của ranh giới rõ ràng. Bằng cách sử dụng một DataContract, bạn đang xuất bản cấu trúc của các kiểu trả về của bạn theo cách lỏng lẻo.

+2

WCF của tôi đang được tiêu thụ bởi các ứng dụng được viết bởi tôi, vì vậy trong tất cả các mục đích thực tế, nó sẽ là ok (để làm hỏng SOA). Bạn có đồng ý không? – Blankman

+1

Bạn có thể có thể, nhưng tại sao bạn muốn? Thêm thuộc tính là không đau và là cách được khuyến khích để làm việc với WCF. –

+0

Scott, vì vậy tôi chỉ cần thêm MyUserCollection của tôi vào lớp CompositeType và bingo !? – Blankman

26

Một điều thú vị khác cần chú ý, là nếu bạn trang trí mã của mình với DataContract, bạn có rất nhiều quyền kiểm soát về những gì khách hàng có thể thấy và phải gửi lại cho dịch vụ của bạn. Ví dụ:

[DataContract] 
public class SampleClass 
{ 
    [DataMember(IsRequired=true)] 
    public int MyRequiredProperty { get; set; } 

    [DataMember] 
    public int MyOptionalProperty { get; set; } 

    public int MyInternalProperty { get; set; } 
} 

Ví dụ trên, bạn xác định khi nhận dữ liệu, bạn PHẢI có MyRequiredProperty và bạn có thể có hoặc không MyOptionalProperty. Ngoài ra, khách hàng sẽ không bao giờ nhìn thấy MyInternalProperty (điều này có thể là ví dụ một số tài sản giúp với logic của bạn nội bộ, nhưng bạn không muốn nó được tiếp xúc ở cấp độ khách hàng).

2

Tôi không đồng ý với người đăng những người đã nói "DataContract chỉ là định nghĩa chính thức của một loại có thể được hiểu trên cả hai mặt của ranh giới dịch vụ."

Từ khóa ở đây là "loại". Trong .NET, một kiểu là một đối tượng có thể có các trường, thuộc tính và phương thức. Tuy nhiên, khi bạn trang trí một lớp học với DataContract trong dịch vụ WCF của bạn, kết quả không phải là lớp được đưa vào ma thuật một cách kỳ diệu; không phải bằng một cú sút xa! Trong mã gọi, bạn sẽ có một lớp "proxy". Lớp proxy nhận XML đại diện cho nội dung của hợp đồng dữ liệu. Mã gọi có thể nhận các giá trị XML này thông qua lớp proxy, nhưng nó không không cấp quyền truy cập mã gọi vào bộ phận bên trong của lớp trang trí với datacontract.

+0

Tuyên bố của bạn "một loại là một đối tượng" là khó hiểu và gây hiểu nhầm. Đối tượng là một loại kiểu, như Số nguyên và Chuỗi là các kiểu. Chỉ cần cho rõ ràng, loại là một định danh của đối tượng là một, String khác, như là số nguyên, Boolean, vv – htm11h

2

Đối với việc trả lời để "marc_s":

"Nếu bạn có NET trên cả hai đầu của dây , đó chỉ là tốt thế nào nếu bạn có một khách hàng Java gọi dịch vụ của bạn Nếu bạn.? Đặt dữ liệu của bạn bên trong DataContracts, thông tin đó được được lưu trữ trong siêu dữ liệu WSDL/XSD và có thể được sử dụng bởi các khách hàng khác ngoài số .NET. "

Tôi nghĩ rằng đó là sai.Chúng ta hãy cố gắng làm điều này:

  1. Sử dụng các ví dụ mặc định của dự án WCF với một lớp học với DataContract thuộc tính trên lớp và DataMember trên các thành viên, và một phương pháp trả về loại này.
  2. Tạo và hiển thị wsdl. Xsd chứa định nghĩa CompositeType. ĐƯỢC.
  3. Bây giờ, hãy xóa tất cả các thuộc tính DataContract và DataMember
  4. Tạo và hiển thị wsdl. Các xsd vẫn chứa định nghĩa ComposityType! (rõ ràng hơn với SCM mềm, cho thấy không có sự khác biệt nào giữa các tệp giữa các bước 2 và 4)

Vì vậy, một khách hàng Java nên quản lý điều này, không có DataContract và DataMember! Tôi sai hay sao?

+2

Bạn không sai, Walter. (I kid, I kid) Thỏa thuận là người tiêu dùng của bạn vẫn cần biết định dạng, đúng không? Nếu bạn đang ở trong NET-đất trên cả hai mặt, bạn tốt bằng cách đơn giản tham chiếu các đối tượng. Bạn không thể nhập một đối tượng .NET vào Java [dễ dàng], vì vậy bạn phải hiển thị định dạng theo cách khác.Không chắc tại sao 4 lại là sự thật - tôi tin rằng thỏa thuận là nó không nên, đúng không? Mặc dù thừa nhận tôi chủ yếu ở đây để có cơ hội trích dẫn El Duderino. – ruffin

11

Có một cách sử dụng quan trọng khác, Bạn có thể thay đổi Tên lớp và thuộc tính. Đó là một tính năng tiện dụng trong quá trình serialization và deserialization.

[DataContract(Name="EmployeeName")] 
public class Person 
{ 
    [DataMember(Name="FullName")] 
    public string Name { get; set; } 

    [DataMember(Name="HomeAddress")] 
    public string Address { get; set; } 
} 
0

Có lẽ không thường được sử dụng, chúng tôi có thể sử dụng [DataContract] để chuyển qua các biến riêng tư. DataContractSerializer sẽ tuần tự hóa/deserialize chỉ các loại hiển thị công khai nếu thuộc tính [DataContract] không được sử dụng.

[DataContract] 
public class SampleClass 
{  
    [DataMember] 
    private int MyPrivateProperty { get; set; } 
} 

(Lưu ý: Nếu bạn đang tạo ra một proxy sau đó các thành viên tin được tiếp xúc như công cộng)

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