嘿,我似乎无法访问我在主机上调用的方法的返回值。
//Service---------------------------------------------------------
[DataMember]
private List<CalculationRecord> History = new List<CalculationRecord>();
public IEnumerable<CalculationRecord> CalculationHistory()
{
return (IEnumerable<CalculationRecord>)History;
}
public CalculationResult Calculate(CalculationNode problem)
{
CalculationResult calcResult = new CalculationResult();
//Calculates results of expression
CalculationEvaluation Evaluator = new CalculationEvaluation();
Evaluator.Calculate(problem, calcResult);
return calcResult;
}
//interface---------------------------------------------------------
[ServiceContract]
public interface ICalculate
{
[OperationContract]
CalculationResult Calculate(CalculationNode problem);
[OperationContract]
IEnumerable<CalculationRecord> CalculationHistory();
}
//Client------------------------------------------------------------
CalculatorClient client = new CalculatorClient();
ICalculate calcProxy = client.ChannelFactory.CreateChannel();
CalculationNode calcRootNode = parser.Parse(expression);
CalculationResult result = calcProxy.Calculate(calcRootNode);//result is null
最佳答案
您有一个错误的印象 - 服务器公开的 DataContract 可以(并且应该)仅包含数据 - 绝不包含任何行为。因此,您永远无法在客户端和主机之间共享对象 - 您可以共享的只是要调用的服务方法以及在这些方法上使用的具体类型。就是这样。
过程是这样的:当客户端连接到服务器时,它将下载服务的元数据 - 它可以找出可用的服务方法,这些方法需要哪些数据 - 但它不能 推断数据契约上的任何其他方法。它就是不能。然后,客户端构建数据协定类型的精确副本 - 但它是一个完全独立的类,并且就其在 XML 中的序列化表示而言,它仅与服务器端数据协定类匹配。它不属于同一类 - 只是看起来相同。
因为最终,服务器和客户端之间发生的所有事情都是序列化消息的交换 - 基本上是一个 XML 文本文档。您没有通过 .NET 对象发送!您所交换的只是数据合约的数据表示,仅此而已。
因此,在您的情况下,客户端代理将有一个新类,它看起来像服务器使用的类 - 至少在网络上的序列化级别上 - 但它将不包含 计算
方法。您调用的 Calculate
方法位于服务契约(Contract)中 - 它不是您拥有的数据成员上的方法。
在您的具体示例中,您似乎也将 [DataMember] 和服务接口(interface)定义混合在一起。不惜一切代价避免这种情况。此外,计算中涉及的所有类型 - 最明显的是 CalculationNode
和 CalculationResult
- 必须公开为包含许多 [DataMember] 字段或属性的 [DataContract] 元素。从您发布的代码片段中并不清楚这一点。
关于.net-4.0 - WCF 在客户端和主机之间共享对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2503213/