views:

69

answers:

3

I'm writing a .net WCF service. I've written a few classes that I want to return to the calling code from the WCF service; hence, I decorate them with the DataContract attribute.

Let's suppose that my WCF service is called FooService. It contains a method called FooMethod which returns an object of type FooData (which is decorated with the DataContract attribute. Suppose that FooData contains a list of numbers and a method called FooAverage which returns the average value of the numbers.

In Visual Studio, I create a new application to consume the service. I add a new "Service Reference" to my WCF Service and give it the namespace myWcfService. In my client code, I instantiate a proxy class and get a connection to the service. To get the FooData object from my proxy, the method call is myWcfService.FooMethod(). It returns an object of type myWcfService.FooData, which is a type determined from the FooService metadata.

Now that I have my object of type myWcfService.FooData, how can I get this data into an object of type FooData as the original type from the service code so that I can call FooData.FooAverage()?

Edit: I am entirely aware of the fact that data comes down the pipe in XML format and that the logic of the methods in a class decorated with DataContract does not get returned by the service; it isn't serializable. What I'm asking is: if I can reference the class that contains the DataContract class used in the service, is there a straightforward way to de-serialize the data into the class that it was serialized from?

I am willing to accept the answer that it is not possible with the current .net framework.

+1  A: 

WCF will allow types to be re-used if they are contained in the project. If your data types are in a Common project somewhere then those types are re-serialized (so long as they have a default constructor and are marked for serialization).

That's only half your question though. If you want your datatype to proxy to the server the method call implementation then you might want Remoting (http://msdn.microsoft.com/en-us/library/ms973857.aspx) and use a Proxy object.

Nate Zaugg
+1  A: 

You cannot.

You need to keep two things completely separate:

  • you have service contracts which define the methods (decorated with [OperationContract] attributes)

  • those methods might need class types, which you define using [DataContract] attributes

The nature of WCF is that the parameters and types going from client to server are serialized into an XML representation - so all you can send across the wire in the form of data contracts is raw data - no behavior - you cannot send across a DataContract class and call a method on it.

In a normal setup, your client-side data classes are not even the same type as they are on the server side - they just look the same in their XML serialized format. All they share is their XML serialization - the data elements that get serialized, nothing more. WCF is not some remote-procedure call method - it sends data-only messages between client and server (and that's a good thing! (tm) ).

If you need to be able to call a method, add that method to your service contract as a method decorated with the [OperationContract] attribute.

marc_s
A: 

You can extend myWcfService.FooData with a partial class definition and define FooAverage() in the client, if the original FooAverage() doesn't have any dependencies that prohibit this:

partial class FooData
{
  public double FooAverage() { return Math.Average(Numbers); }
}

But remember that FooData is a data transfer object, and as such does not have any private state, which means that you can put all the data into non-member functions anyway:

double average = Math.Average(foodata.Numbers);
Ozan