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,这就行得很好.使用这种方法可以实现任何互操作性.
你正在将两个概念与你的Person类型混合在一起- 你所做的事情是行不通的.
你已经DataContract在Person类型上加了一个属性.这是正确的,因为你有一个返回的服务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属性不会神奇地将数据传输对象转换为服务.