If you're doing POX/REST programming using the WCF HTTP Transport on the Feb CTP, you need to use the following setting for HttpTransportBindingElement.MappingMode:
- On the client side, use HttpMappingMode.AnyXml
- On the service side, use HttpMappingMode.Soap
Ultimately we plan to have HttpMappingMode.AnyXml be the thing to use for POX/REST on both sides, but unfortunately it's not that way right now.
In case you're interested, here's the long story behind this knob.
Back in the Beta1 days of Indigo, we had a knob on the HttpTransportBindingElement called MapAddressingHeadersToHttpHeaders.
Setting this to "true" on the server enabled us to handle lots of interesting scenarios where the message on the wire didn't have a wsa:To header. When MapAddressingHeadersToHttpHeaders was set to "true", we'd take the Request URI from the underlying HTTP message and cons up an equivalent WS-Addressing [destination] MAP prior to handing the message up the channel stack.
This is how we made our dispatch infrastructure (which assumes that the WS-Addressing Message Address Properties [MAPs] are always present) deal with messages that didn't really use WS-Addressing. Such scenarios include WS-I Basic Profile compilance as well as POX/REST cases that use HTTP natively, so this is a pretty important feature from a scenario completeness perspective.
MapAddressingHeadersToHttpHeaders also had meaning on the client side. There, we'd look at the wsa:To header of the outbound message and map it to Request URI of the outbound HTTP Request. We'd also map the wsa:Action MAP to the SOAPAction HTTP header in this mode.
With me so far? Good. Let's switch gears a bit.
When you're doing HTTP programming, often times you end up with response messages that don't have an actual protocol body because all the interesting data is conveyed by the HTTP response headers (e.g. just a status response like 202 ACCEPTED). In "SOAP Mode", the Indigo HTTP transport just surfaces these bodiless responses up the channel stack as null references, because an empty HTTP response isn't an interesting SOAP message.
For POX/REST scenarios (where the app code cares deeply about HTTP response properties like status code), the behavior we had in place for bodiless responses was problematic. We expose the HTTP status code by sticking it in the Message.Properties collection which (of course) requires an actual instance of the message. It's pretty hard to reach into null.Properties to pull our the HttpResponseMessageProperty, and that's exactly what the Beta 1 design was telling us to do.
Rather than adding another knob (which would have semantically been something like "I care about bodiless responses"), we decided to make MapAddressingHeadersToHttpHeaders a tri-state. Thus was born the HttpMappingMode enumeration that we know and love today.
The semantic mapping between the two is as follows:
- HttpMappingMode.SoapWithWSAddressing == MapAddresingHeadersToHttpHeaders( false )
- HttpMappingMode.Soap == MapAddresingHeadersToHttpHeaders( true )
- HttpMappingMode.AnyXml == MapAddresingHeadersToHttpHeaders( true ) + special handling for bodiless responses
That's the ultimate intent, anyway. There's a bug in the Feb CTP that prevents HttpMappingMode.AnyXml from properly mapping the HTTP Request URI into the WSA [destination] MAP. As such, setting HttpMappingMode.AnyXml on the server renders the services using that binding unreachable. This manifests as HTTP 500 error coming back to the client, and strange "endpoint unavailable at this time" exceptions on the server.So
So as I mentioned above, the workaround for you POX/REST folks is to use HttpMappingMode.Soap on the server for the time being. HttpMappingMode.AnyXml is still the right thing to do on the client.
We'll get this bug fixed ASAP.
