Implementing a POX HTTP service

WCF services by default use SOAP as the message format of service operations, which means each message transferred between the client and service is wrapped in a SOAP envelope that contains one SOAP body and some SoapHeaders. However, sometimes our WCF service will need to work with some legacy POX (Plain Old XML) clients or our WCF-based client will need to talk to some POX-style service. In such cases, it is necessary to let our WCF client or service generate arbitrary XML messages without strictly obeying the SOAP standard.

How to do it...

We will use a CustomBinding to build a POX-enabled WCF service and consume it with a POX-enabled WCF client program. Let’s have a look at the complete steps:

  1. The first thing to do is to make our ServiceContract POX ready. The following code shows a sample operation that is ready for exchanging POX-style messages.
      [OperationContract(Action=”*”,ReplyAction=”*”)]
             Message SayHello(Message reqMsg);

    Compared with normal service operation, one obvious difference is that we’ve used the System.ServiceModel.Channels.Message class as the only input parameter and return value.

  2. For the service endpoint, we will need to apply a custom binding on it. This binding will utilize the HTTP transport layer and set the messageVersion as None. The following screenshot shows the complete definition of our custom binding:
    How to do it...
  3. After the service endpoint has been configured, we can start the service and consume it with POX-enabled clients. For the service side, we can directly get the XML content from the input Message parameter. When returning the result, we also need to construct a Message instance and assign it the proper HTTP properties, if necessary. The following code demonstrates a simple message processing scenario:
    public Message SayHello(Message reqMsg)
    {
       // Process request message
       Console.WriteLine(reqMsg.GetBody<XElement>());
       // Construct response message
       HttpResponseMessageProperty properties = new HttpResponseMessageProperty() { StatusCode = System.Net.HttpStatusCode.OK }; 
     Message repMsg = Message.CreateMessage(MessageVersion.None, string.Empty, new XElement(“HelloResponse”,“Hello POX Client!”));
       repMsg.Properties[HttpResponseMessageProperty.Name] = properties;
       return repMsg;
    }
  4. The same code logic applies to the client side if we’re using a WCF client to send POX requests to another service. The following code snippet demonstrates sending a POX request with a simple XML element as the entire message body:
    ChannelFactory<TestClient.IPOXService> factory = new ChannelFactory<IPOXService>(“POXEndpoint”);
    TestClient.IPOXService client = factory.CreateChannel();
    
    HttpRequestMessageProperty properties = new HttpRequestMessageProperty() { Method = “POST” };
     Message reqMsg = Message.CreateMessage(MessageVersion.None,string.Empty, new XElement(“HelloRequest”,“Hello POX Service!”));
    reqMsg.Properties[HttpRequestMessageProperty.Name] = properties;
    
    Message repMsg = client.SayHello(reqMsg);
    Console.WriteLine(repMsg.GetBody<XElement>());
    

How it works...

In the SayHello POX service example we just looked at, there are two key points that enable the service to exchange a POX-style message:

  • CustomBinding with messageVersion as None
  • Message type input parameter and return value

By setting messageVersion (of the <textMessageEncoding> binding element) to None, the WCF runtime will no longer force any SOAP format requirement on the exchanging messages.

Also, the System.ServiceModel.Channels.Message type allows us to freely construct arbitrary XML-style messages for service requests and responses.

By capturing the request/response messages on wire, we can confirm that the underlying operation messages are of plain XML format instead of SOAP envelope-based format, as shown in the next screenshot:

How it works...

There’s more...

This recipe uses a CustomBinding to build a POX-enabled service; however, this is not the only way to build POX-style services in WCF. The WCF REST programming model is another good way to build services that can process plain XML messages. And if you’re familiar with web application development, you will find the REST programming model much more convenient and familiar.

We will discuss more about the WCF REST programming model in Chapter 10, RESTful and AJAX-enabled WCF Services.

See also

  • Complete source code for this recipe can be found in the \Chapter 2\recipe5\ folder