WCF Совместное использование объекта между клиентом и хостом

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

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

Решение

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

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

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

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

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

Другие вопросы по тегам