views:

146

answers:

1

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

+1  A: 

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.

marc_s
I updated my question... I'm not sure how to call the service if I don't define a UriTemplate on the WebInvoke since requests are posted to this service. I just posting to the service link itself and it bombed out. You're saying I can post the xml to the same URL and have .Net auto determine which function gets hit? Thats what I'm clueless about.
Chris Klepeis
From your example above, and my limited understanding... those functions would be accessed from http://site.com/service.svc/YourMethodNo1, http://site.com/service.svc/YourMethodNo2, http://site.com/service.svc/YourMethodNo3, etc which is what I want to avoid
Chris Klepeis
@Chris: no, this is not correct - all five functions would be accessed at site.com/service.svc as the service URL.
marc_s
The client code is inaccessible. The only stipulations are: the xml will be posted in text/xml format and we need to provide an endpoint.
Chris Klepeis
Perhaps I can build it as you propose then create a simple aspx file which takes the posted xml, and I call the appropriate WCF function and return the data
Chris Klepeis
@Crhis: yes, you could probably create a single "entrypoint" - a WCF REST service so the XML can be posted directly, and then dispatch it to a WCF service of your own with several separate methods to deal with the various service methods for the different sets of parameters. Sounds like a plan!
marc_s