R – WCF XML Serialization & Overloading

serializationwcfxmlxml-serialization

In my WCF service I only want 1 endpoint (1 URI), however, I want this URI to be able to handle multiple types of requests. 5 different request types can be sent to this service from another company. Each request has a unique XML schemas.

I created classes for each XML request to be serialized. Normally I would just overload a function when the parameter is different…. however I cannot do this in this instance because the UriTemplate of my WCF functions are the same, and throws errors when I try to run the app (saying the UriTemplate must be unique).

In each XML request is a node named "requestType". I'm trying to get a feel for what others would do… should I serialize on my own and ignore the built in serialization from the DataContract? What type of parameter should I set my function to accept… an XMLDocument then based on the requestType branch out to the request specific logic?

The returned XML from this function is also unique based on the request type…. however I cannot return an XMLDocument from an OperationContract… more errors are thrown (I think because it said it cannot be serialized).

I've tried creating a class that can get serialized from all request types by setting

IsRequired = false, EmitDefaultValue = false

…on the DataMembers for objects that are not shared amongst the different request types. I'm now running into a problem where the Order has to be properly set for each DataMember otherwise it doesn't get serialized at all into my class object…. I would have thought the Order wouldn't have to be set :/

Edit:

This is what I'm using now… the XML is POSTed to my service.

[WebHelp(Comment = "comment")]
[WebInvoke(UriTemplate = "foobar",
            Method = "POST",
            BodyStyle = WebMessageBodyStyle.Bare,
            ResponseFormat = WebMessageFormat.Xml)]
[OperationContract]
public ResponseType foobar(ReqeustType request)
...

When testing I would post XML to http://localhost:4011/XMLWCF/Service.svc/foobar

Best Answer

I would have one service endpoint, e.g. one URL, but I would clearly define five separate, unique service methods in your service contract, and implement those separately.

THat's by far the easiest and cleanest solution, in my opinion.

[ServiceContract(Namespace=".......")]
interface IYourService
{
   [OperationContract]
   ReturnValue1 YourMethodNo1(int a, int b);

   [OperationContract]
   ReturnValue2 YourMethodNo2(........);

   [OperationContract]
   ReturnValue3 YourMethodNo3(..........);

   [OperationContract]
   ReturnValue4 YourMethodNo4(...........);

   [OperationContract]
   ReturnValue5 YourMethodNo5(........);
}

You can't really have just a single service method which gets five different types of parameters. Also, WCF doesn't support method overloading - since WSDL doesn't support it. All your methods have to have a unique name and have to have defined and clear parameters types.

You could use a general parameter of type Message - but that does get pretty hairy, in my opinion. This MSDN page or this blog post shed some light on how to do that - if you really want to...

UPDATE: in this scenario I described, you'd have ONE service URL - http://site.com/service.svc.

From that service URL, you'd create a client proxy at your client end, which would have five methods to call:

(pseudo-code):

class ClientProxy
{       
   ReturnValue1 YourMethodNo1(int a, int b);
   ReturnValue2 YourMethodNo2(........);
   ReturnValue3 YourMethodNo3(..........);
   ReturnValue4 YourMethodNo4(...........);
   ReturnValue5 YourMethodNo5(........);
}

From your client code, you would then call either of those five methods:

ReturnValue1  result = ClientProxy.YourMethodNo1(5, 7);

but all would go to the single service URL.

Related Topic