WCF在客户端和主机之间共享对象

时间:2010-03-23 20:06:06

标签: .net-4.0 wcf c#-4.0 wcf-client

嘿,我似乎无法从我在Host上调用的方法中访问返回的值。

    //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

1 个答案:

答案 0 :(得分:4)

您的印象错误 - 服务器公开的DataContract可以(并且应该)包含数据 - 绝不会有任何行为。因此,您可以从不在客户端和主机之间共享对象 - 您可以共享的是要调用的服务方法,以及要在这些方法上使用的具体类型。而已。

流程是这样的:当客户端连接到服务器时,它将下载服务的元数据 - 它可以找出可用的服务方法,采取的数据 - 但不能推断数据合同的任何其他方法。它只是不能。然后,客户端构建数据协定类型的精确副本 - 但它是一个完全独立的类,它只与服务器端数据协定类匹配,就其在XML中的序列化表示而言。它是同一个类 - 它看起来一样。

因为最终,服务器和客户端之间发生的所有事情都是交换序列化消息 - 基本上是XML文本文档。您发送.NET对象!你所交换的只是数据合同的数据表示,仅此而已。

因此,在您的情况下,客户端代理将有一个新的类,看起来像服务器使用的类 - 至少在线上的序列化级别 - 但它包含{ {1}}方法。您正在调用的Calculate方法是在服务合同上 - 它您拥有的数据成员上的那个。

在您的具体示例中,您似乎正在混合[DataMember]和服务接口定义。不惜一切代价避免这样做。此外,计算中涉及的所有类型 - 绝对是CalculateCalculationNode - 必须作为包含许多[DataMember]字段或属性的[DataContract]元素公开。从您发布的代码片段中可以看出这一点。