Question

I'm trying to create a WCF client to send XML messages to a CGI script. The script functions in a request-response pattern, where the contents of the XML message will determine the action to invoke.

I've starting by creating a service contract to represent the defined set of documents the CGI script will accept:

[ServiceContract]
public interface ICgiService
{
    [OperationContract(Name="request1")]
    [WebInvoke(BodyStyle = WebMessageBodyStyle.Bare)]
    ServiceResponse SubmitRequest(Request1 request);

    [OperationContract(Name="request2")]
    [WebInvoke(BodyStyle = WebMessageBodyStyle.Bare)]
    ServiceResponse SubmitRequest(Request2 request);

    [OperationContract(Name="request3")]
    [WebInvoke(BodyStyle = WebMessageBodyStyle.Bare)]
    ServiceResponse SubmitRequest(Request3 request);
}

I have generated a proxy client from this interface and configured the endpoint with the address to the CGI script and to use HTTP Transport.

When a request is made, the default behaviour of the WCF runtime is to append the operation name to the endpoint address to make the URI http://server/script.cgi/request1.

How do I modify this behaviour so all requests are sent to the endpoint address without any changes to the URI (e.g http://server/script.cgi)?

Was it helpful?

Solution 2

In the end, what I wanted to achieve doesn't seem simple through out-of-the-box WCF at this time.

To achieve direct control over the addressing, you can implement an IClientMessageFormatter and set the To header value directly, but this is a very heavy interface to be implementing, potentially causing other problems.

To solve my problem I refactored the service contract into:

[ServiceContract]
public interface ICgiService
{
    [OperationContract(Name="script.cgi")]
    [WebInvoke(BodyStyle = WebMessageBodyStyle.Bare)]
    ServiceResponse SubmitRequest(ServiceRequest request);
}

It doesn't allow me to specify the CGI script URL as the full endpoint address, being treated as REST service where the script is a resource.

Additionally, the ServiceRequest class now has to represent all the possible XML structure for each type of request, making the service contracts much harder to understand.

Arguably, this is much closer to the real-world situation: posting various XML documents to a single CGI script that provides a single operation "Do Stuff".

OTHER TIPS

You need to supply a URI template to your service operations:

[WebGet(UriTemplate="/")]

(if you're using a GET verb), or

[WebInvoke(UriTemplate="/", Method="POST")]

(if you're using a POST verb).

The UriTemplate can be anything, and it'll be appended to the base URL where the service lives. When you need a GET operation, use [WebGet()] attribute - when you need anything else, use the [WebInvoke(Method="....")] attribute and define what verb you need.

Check out the MSDN Magazine article An Introduction To RESTful Services With WCF for a great intro to WCF and REST.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top