2010-11-06 27 views
7

Tôi đang cố gắng chơi với WCF và tôi nghĩ rằng tôi đã đánh một khối. Vấn đề của tôi là tôi có thể gọi Add(double,double)getPerson() từ "Khách hàng". Tuy nhiên, tôi không thể gọi bất kỳ phương thức nào của đối tượng Person. Tôi đã loại bỏ các lớp học bằng các phương pháp trần. Dưới đây là đoạn mã của tôi, xin vui lòng cho tôi biết những gì tôi đang làm sai ..WCF trả lại đối tượng cho khách hàng

Server Code

namespace Test.WebSvc{ 
    [ServiceContract(Namespace = "http://Microsoft.ServiceModel.Sample")] 
    public interface ICalculator 
    { 
    [OperationContract] 
    double Add(double n1, double n2); 
    [OperationContract] 
    Person getPerson(); 
    } 


public class CalculatorService : ICalculator 
{ 
    public double Add(double n1, double n2) { return n1+n2 ; } 
    public Person getPerson(){ 
    Person tempPerson = new Person(); 
    return tempPerson; 
    } 
} 

[DataContract] 
public class Person{ 
[OperationContractAttribute] 
public string toString(){ 
return "This is a Person Object"; 
} 

Client Code

ServiceRef1.CalculatorClient client = ServiceRef1.CalculatorClient();//works 
Console.WriteLine(client.Add(1.0,2.0)); //this too works 
ServiceRef1.Person p = client.getPerson(); // this is OK., but is not doing what I wanted it to do 
Console.WriteLine(p.toString()); // I do not get "This is Person Object" 

Tôi đoán điều gì đó xảy ra với tuyên bố của tôi lớp Person .. nhưng dint có được một đầu mối những gì tôi nên làm hoặc những gì tôi đang thiếu ..

Cảm ơn!

Trả lời

8

Bạn đang trộn hai khái niệm với loại Person của mình - những gì bạn đang làm sẽ không hoạt động.

Bạn đã đặt thuộc tính DataContract trên loại Person. Điều này là chính xác, bởi vì bạn có một dịch vụ trả lại Person. Đối tượng Person sẽ được tuần tự hóa và trả về cho máy khách dịch vụ của bạn (CalculatorClient trong trường hợp này).

Bạn nên xác định Person như thế này:

[DataContract] 
public class Person 
{ 
    [DataMember] 
    public string Description { get; set; } 
} 

Và trong dịch vụ máy tính của bạn:

public Person getPerson() 
{ 
    Person tempPerson = new Person(); 
    tempPerson.Description = "This is a Person Object"; 
    return tempPerson; 
} 

Điều này là do việc Person đối tượng của bạn là để giữ dữ liệu, và mang nó từ máy chủ cho khách hàng . Nó không phải là công việc của nó để xác định phương pháp/hoạt động, mà thay vào đó nên được thực hiện trong các lớp dịch vụ của bạn (ví dụ: CalculatorService). Việc thêm thuộc tính OperationContract không biến đối tượng chuyển dữ liệu thành một Dịch vụ một cách kỳ diệu.

+0

Hãy cho tôi một phút để làm việc ra rằng DataContract không phải là một phần của ServiceModel Namespace. Trong System.Runtime.Serialization của nó và bạn cũng sẽ cần phải thêm một tham chiếu trong dự án của bạn vào nó – Knightsy

10

Có, bạn đã đạt đến rào cản - WCF là hệ thống dựa trên tin nhắn chỉ trao đổi dữ liệu được tuần tự, dưới dạng XML hoặc JSON, ở định dạng văn bản hoặc nhị phân. Nó có không phải là tuy nhiên chuyển các đối tượng .NET đầy đủ với đầy đủ các khả năng như phương thức và tất cả (như thế nào? Nó được thiết kế là tương thích và tôi không thấy cách khách hàng của Ruby hoặc PHP có thể gọi một phương thức trên đối tượng .NET).

WCF không được thiết kế để làm cho nó có thể truy cập từ xa các đối tượng - nó chỉ truyền các thông điệp giữa máy khách và máy chủ. Do đó, bất cứ điều gì bạn có thể thể hiện trong lược đồ XML (các kiểu nguyên tử, bất kỳ thứ gì như kế thừa và thành phần) đều có thể được sắp xếp và gửi đi giữa hai bên.

Bất cứ điều gì mà không thể được lập mô hình trong lược đồ XML - như generics, interfaces, methods/code - không thể được truyền giữa máy khách và máy chủ.

Có nhiều cách và thủ thuật để giải quyết vấn đề này nếu bạn kiểm soát cả hai đầu của giao tiếp và cả hai đều là .NET. Về cơ bản, bạn sẽ phải đặt hợp đồng dịch vụ và tất cả các hợp đồng dữ liệu (tất cả các lớp của bạn) vào một hội đồng riêng biệt, sau đó bạn tham chiếu từ cả máy chủ (thực hiện hợp đồng dịch vụ) và từ khách hàng gọi đến hợp đồng.Bạn có thể yêu cầu WCF sử dụng lại các kiểu đã tồn tại trong các assembly được tham chiếu, và trong trường hợp này, máy khách sẽ sử dụng lại lớp sẵn sàng Person (với tất cả sự tốt lành .NET) từ assembly chung của bạn thay vì tạo proxy dữ liệu phía máy khách. Với thủ thuật này, bạn có thể có WCF gửi các thông điệp tuần tự qua dây, nhưng ở phía máy khách, bạn đang tái tạo một đối tượng .NET đầy đủ với tất cả các phương thức của nó và tất cả.

Một lần nữa: điều này hoạt động tuyệt vời miễn là bạn kiểm soát cả hai đầu của giao tiếp và cả hai đầu đều sử dụng .NET. Bất kỳ khả năng tương tác nào cũng nằm ngoài cửa sổ với cách tiếp cận này.

+0

+1 Giải thích dữ liệu tuần tự hóa –

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