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]. Это не ясно из фрагмента кода, который вы разместили.