WCF Совместное использование объекта между клиентом и хостом - PullRequest
2 голосов
/ 23 марта 2010

Эй, я не могу получить доступ к возвращенному значению из метода, который я вызвал на моем хосте.

    //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 Ответ

4 голосов
/ 24 марта 2010

У вас неправильное впечатление - DataContract, который предоставляет сервер, может (и должен) только содержать данные - никогда никакого поведения. Таким образом, вы можете никогда обмениваться объектами между клиентом и хостом - все, что вы можете поделиться - это сервисные методы для вызова и конкретные типы для использования в этих методах. Вот и все.

Процесс таков: когда клиент подключается к серверу, он загружает метаданные для службы - он может узнать, какие методы службы доступны, какие данные они принимают - но он не может сделать вывод о любых дополнительных методах на основе данных контракта. Это просто не может. Затем клиент создает точную копию типа контракта данных - но это совершенно отдельный класс, и он соответствует только классу контракта данных на стороне сервера, если речь идет о его сериализованном представлении в XML. Это не того же класса - он просто выглядит одинаково.

Потому что, в конце концов, все, что происходит между сервером и клиентом, это обмен сериализованным сообщением - в основном текстовым документом XML. Вы не отправляете через объект .NET! Все, что вы обмениваетесь, - это представление данных вашего контракта с данными, ничего более.

Так что в вашем случае прокси на стороне клиента будет иметь новый класс, который выглядит как тот, который использует сервер - по крайней мере, на уровне сериализации на проводе - но он будет не содержать Calculate метод. Метод Calculate, который вы вызываете, указан в договоре на обслуживание - это , а не тот, который у вас есть.

В вашем конкретном примере тоже - вы, кажется, смешиваете [DataMember] и определение интерфейса сервиса. Избегайте этого любой ценой. Кроме того, все типы, участвующие в вычислении - наиболее определенно CalculationNode и CalculationResult - должны быть представлены как элементы [DataContract], содержащие ряд полей или свойств [DataMember]. Это не ясно из фрагмента кода, который вы опубликовали.

...