Share via


Making One-Way HTTP Requests, Part 3

We've been looking at the mystery of why one-way messages stop working when you turn on the POX message encoder. The clues to solving this mystery are that:

  1. The service does not change its behavior at all when the message encoder is changed.
  2. The failure happens with the POX message encoder but not the text message encoder.
  3. The exception we get is that the OneWay channel unexpectedly got a message back.

The solution to this mystery is back in the original description of why we added the POX message encoder in the first place. One of the properties of the standard message encoders is that they only surface up messages that have a non-empty message body. In the POX case, you sometimes want to process messages based solely on the contents of the HTTP headers and you don't actually care at all about the message body. The POX message encoder replaces the original HttpMappingMode feature that controls whether we turn empty HTTP message into null SOAP messages or empty SOAP messages. The standard text message encoder returns a null SOAP message. The POX message encoder returns an empty SOAP message so that you can still look at the HTTP headers that were included.

Of course, now a failure is inevitable because the OneWay channel is looking for a null SOAP message to come back. When you're using the POX message encoder, it gets back an empty SOAP message rather than a null SOAP message and assumes that something has gone wrong with the one-way protocol.

Fixing this is a little tricky. You need to somehow cause the SOAP message to disappear before it hits the OneWay channel. However, you should only eat the response when the message was successfully handed off because you want to report back any server errors. My idea is to key this off of the status code in the HTTP response. If a message comes back and it has the 202 Accepted status code, pretend like it was really a null SOAP message. Otherwise, pass the message along unchanged. If you're interested in supporting this scenario, you might want to do some other variation depending on how your server behaves.

 Message FilterMessage(Message reply)
{
   if (reply == null)
   {
      return null;
   }
   HttpResponseMessageProperty properties = (HttpResponseMessageProperty)reply.Properties[HttpResponseMessageProperty.Name];
   if (properties != null && properties.StatusCode == HttpStatusCode.Accepted)
   {
      return null;
   }
   return reply;
}

I'll write up a channel for Monday that you can stick in your channel stack to apply this filter.

Next time: ReplyMangler Channel