Hey, I can’t seem to access the returned value from a method I called on my 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
You’re under a wrong impression – the DataContract that the server exposes can (and should) only contain data – never any behavior. As such, you can never share an object between client and host – all you can share are service methods to call, and concrete types to use on those methods. That’s it.
The process is this: when the client connects up to the server, it will download the metadata for the service – it can find out what service methods are available, what data those take – but it cannot infer any additional methods on the data contract. It just can’t. The client then builds up an exact copy of the data contract type – but it’s a totally separate class, and it only matches the server-side data contract class as far as its serialized representation in XML is concerned. It is not the same class – it just look the same.
Because in the end, all that happens between the server and the client is an exchange of a serialized message – basically a XML text document. You are not sending across a .NET object! All you’re exchanging is a data representation of your data contract, nothing more.
So in your case, the client side proxy will have a new class that looks like the one the server uses – at least on the serialized level on the wire – but it will not contain the
Calculatemethod. TheCalculatemethod you’re calling is on the service contract – it’s not the one on the data member you have.In your concrete example, too – you seem to be intermixing [DataMember] and service interface definition. Avoid this at all costs. Also, all the types involved in the calculation – most definitely
CalculationNodeandCalculationResult– must be exposed as [DataContract] elements containing a number of [DataMember] fields or properties. This is not clear from the snippet of code you posted.