Interoperability with POX Applications
“Plain Old XML” (POX) applications communicate by exchanging raw HTTP messages that contain only XML application data that is not enclosed within a SOAP envelope. Windows Communication Foundation (WCF) can provide both services and clients that use POX messages. On the service, WCF can be used to implement services that expose endpoints to clients such as Web browsers and scripting languages that send and receive POX messages. On the client, the WCF programming model can be used to implement clients that communicate with POX-based services.
This document was originally written for the .NET Framework 3.0. .NET Framework 3.5 has built-in support for working with POX applications. For more information about see WCF REST Programming Model |
POX Programming with WCF
WCF services that communicate over HTTP using POX messages use a customBinding element.
<customBinding>
<binding name="poxServerBinding">
<textMessageEncoding messageVersion="None" />
<httpTransport />
</binding>
</customBinding>
This custom binding contains two elements:
The httpTransport element and
The standard WCF Text Message Encoder is specially configured to use the None value, which allows it to process XML message payloads that do not arrive wrapped in a SOAP envelope.
WCF clients that communicate over HTTP using POX messages use a similar binding (shown in the following imperative code).
private static Binding CreatePoxBinding()
{
TextMessageEncodingBindingElement encoder =
new TextMessageEncodingBindingElement( MessageVersion.None, Encoding.UTF8 );
HttpTransportBindingElement transport = new HttpTransportBindingElement();
transport.ManualAddressing = true;
return new CustomBinding( new BindingElement[] { encoder, transport } );
}
Because POX clients must explicitly specify the URIs to which they send messages, they usually must configure the HttpTransportBindingElement to a manual addressing mode by setting the ManualAddressing property to true on the element. This allows messages to be addressed explicitly by application code and it is not necessary to create a new ChannelFactory every time an application sends a message to a different HTTP URI.
Because POX messages do not use SOAP headers to convey important protocol information, POX clients and services often must manipulate pieces of the underlying HTTP request used to send or receive a message. HTTP-specific protocol information such as the HTTP headers and status codes are surfaced in the WCF programming model through two classes:
HttpRequestMessageProperty, which contains information about the HTTP request, such as the HTTP method and request headers.
HttpResponseMessageProperty, which contains information about the HTTP response, such as the HTTP status code and status description, as well as any HTTP response headers.
The following code example shows how to create an HTTP GET request message that is addressed to https://localhost:8100/customers.
Message request = Message.CreateMessage( MessageVersion.None, String.Empty );
request.Headers.To = “https://localhost:8100/customers”;
HttpRequestMessageProperty property = new HttpRequestMessageProperty();
property.Method = “GET”;
property.SuppressEntityBody = true;
request.Properties.Add( HttpRequestMessageProperty.Name, property );
First, an empty request Message is created by calling CreateMessage. The None parameter is used to indicate that a SOAP envelope is not required and Empty parameter is passed as the Action. The request message is then addressed by setting To header to the desired URI. Next, an HttpRequestMessageProperty is created and the Method is set to the HTTP verb GET method and the SuppressEntityBody is set to true to indicate that no data should be sent in the body of the outgoing HTTP request message. Finally, the request property is added to the Properties collection of the request message so it can influence how the HTTP Transport sends the request. The message is then ready to be sent over an appropriate instance of the IRequestChannel.
Similar techniques can be used on the service to extract the HttpRequestMessageProperty from an incoming message and construct a response.