WCF将对象返回给客户端

Sek*_*har 7 wcf serialization web-services object

我正在尝试使用WCF,我想我已经遇到了障碍.我的问题是,我能够调用Add(double,double)getPerson()从"客户".但是,我无法调用任何Person对象方法.我用裸方法剥离了类.这是我的代码片段,请让我知道我做错了什么..

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";
 }
Run Code Online (Sandbox Code Playgroud)

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"
Run Code Online (Sandbox Code Playgroud)

我猜测我的Person类的声明有什么问题..但是dint得到一个线索我应该做什么或者我缺少什么..

谢谢!

mar*_*c_s 11

是的,你遇到了障碍--WCF是一个基于消息的系统,它只以文本或二进制格式交换XML或JSON的序列化数据.然而,它并没有传递"完整"的.NET对象及其全部功能,如方法和所有这些(应该如何?它的设计是可互操作的,我不知道Ruby或PHP客户端如何调用方法一个.NET对象).

WCF的目的不是为了能够远程访问对象 - 它只是在客户端和服务器之间传递消息.因此,您可以在XML模式中表达的任何内容(原子类型,继承和组合等)都可以序列化并在双方之间发送.

任何无法在XML模式中建模的东西- 如泛型,接口,方法/代码 - 都无法在客户端和服务器之间传递.

如果你控制通信的两端并且它们都是基于.NET的,那么有办法解决这个问题.基本上,您必须将服务合同和所有数据合同(所有类)放入一个单独的程序集中,然后从服务器(实现服务合同)和调用合同的客户端引用.您可以告诉WCF重用已引用的程序集中已存在的类型,在这种情况下,客户端Person将从您的公共共享程序集重新使用现成的类(具有其所有.NET优点),而不是重新创建客户端数据代理.通过这个技巧,您可以让WCF通过线路发送序列化消息,但在客户端,您将使用其所有方法重新创建完整的.NET对象.

再说一遍:只要你控制通信的两端,并且两端都使用.NET,这就行得很好.使用这种方法可以实现任何互操作性.


Nad*_*zie 9

你正在将两个概念与你的Person类型混合在一起- 你所做的事情是行不通的.

你已经DataContractPerson类型上加了一个属性.这是正确的,因为你有一个返回的服务Person.该Person对象将被序列化并返回给您的服务客户端(CalculatorClient在本例中).

你应该这样定义Person:

[DataContract]
public class Person
{
    [DataMember]
    public string Description { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

在您的计算器服务中:

public Person getPerson()
{ 
    Person tempPerson = new Person();
    tempPerson.Description = "This is a Person Object";
    return tempPerson; 
}
Run Code Online (Sandbox Code Playgroud)

这是因为您的Person对象的工作是保存数据,并将其从服务器传送到客户端.定义方法/操作不是它的工作,而应该在您的服务类(例如CalculatorService)中完成.添加OperationContract属性不会神奇地将数据传输对象转换为服务.