views:

301

answers:

2

Suppose I have a WCF service and a method in the contract

<ServiceContract()> _
Interface IThingService
'...
  <OperationContract()> _
  Function GetThing(thingId As Guid) As Thing
End Interface

where Thing is an ordinary class with ordinary properties, except for one member:

Public Class Thing
  ' ...
  Public Property Photos() As Dictionary(Of String, Photo) 
  ' ...
End Class

where Photo is an ordinary class with ordinary properties.

So I dove into some documentation such as http://msdn.microsoft.com/en-us/library/aa347850.aspx and http://bit.ly/jA9z3 , and now I am confused if I have to understand a lot about the DataContractSerializer and the particulars of how the service serializes the Photos property.

Do I need to go there, or is there something I can do to let WCF on the server interact with my client automatically? Seems to me all the serialization details should be able to be abstracted away--I just want to end up, in the consuming client app, with:

Dim foo as Thing = ThingServiceClient.GetThing(someGuid)
Dim myPhotos as Dictionary(Of String, Photo) = foo.Photos

What do I need to do in my definition of Thing to make this work? Anything I need to do elsewhere to get this to work? Do I need to worry about ensuring the service sticks to the DataContractSerializer and doesn't fall back to use the XmlSerializer?

A: 

You need to make sure that you decorate your "Thing" with the [DataContract] attribute, and all its members that you want to include in the data contract must have the [DataMember] attribute on them. Same goes for your "Photo" class.

As long as you don't have to deal with polymorphism (inheritance) and/or custom collections, that should be it, really. The rest should be taken care of by the WCF runtime for you.

Marc

marc_s
I don't have the DataContract attribute on any of my classes, and as soon as I add it, I get an exception as follows. Any idea what I'm doing wrong? {"An error occurred while receiving the HTTP response to localhost/MyService/MyService.svc/…. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details."}
Patrick Szalapski
What binding are you using? And what are the server logs telling you?
marc_s
basicHttpBinding, and there's nothing in the server logs.
Patrick Szalapski
+1  A: 

I would be careful with exposing you business objects directly in a WCF contract (or an asmx web service, or any other external entry point into the system). This is an interface that your external systems use, and such an interface should stay constant even though your business objects change internally. There can also be functions on the business object that makes sense on the server, but not on the client.

Also, you suddenly need to modify you bussiness objects so that it fits you communication technology of choice, e.g. you have to put attributes on you business class, attributes that really has nothing to do with the business class.

I would create a ThingDTO (DTO = data transfer object) that contain the data to transfer to the client, and initialize it with the data from a Thing instance. That means that if you consider you WCF service to be a facade to the system, the ThingDTO is then part of your facade layer. And therefore attributes to control WCF serialization can go freely in here.

That said, it is not the same as that it makes sense in your case. That is just my general view on returning business classes from a WCF interface.

Pete