Welcome to Windows Communication Foundation (WCF)
Top Tasks :

WCF Team Bloggers

Browse by Tags

All Tags » Messages and En... » HTTP   (RSS)

  • 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: The service does not change its behavior at all when the message encoder is changed. The failure happens with the POX message encoder but not the text message encoder. 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. Read More...
  • Making One-Way HTTP Requests, Part 2

    The article yesterday left off by stating that while the test program works fine with the messaging defaults, things break when we switch to the POX message encoder. Today and tomorrow, we'll look at what goes wrong, why, and how to fix it. To switch to the POX message encoder, I'm going to change the MessageVersion setting of the normal text message encoder that is already in my binding. You can do this by adding the following line to the test client after creating the custom binding. binding.Elements.Find<MessageEncodingBindingElement>().MessageVersion = MessageVersion.None; Now, when I run the test program, I see the correct and expected output on the server. HTTP/1.1 POST http://localhost:8000/ ::1:1147 --> ::1:8000 [Headers] Connection: Keep-Alive Content-Length: 126 Content-Type: application/xml; charset=utf-8 Expect: 100-continue Host: localhost:8000 [Request] < Ping xmlns ="http://tempuri.org/" > < clientInfo > my info </ clientInfo > < lastSeen > 2006-08-15T00:22:36.528375-07:00 </ lastSeen > </ Ping > All of the SOAP goo is gone from the request. Compared to the request we saw yesterday, the only thing left in the request is what was formerly the contents of the body tag. However, on the client side, there's an exception being thrown after the message gets sent. Unhandled Exception: System.ServiceModel.ProtocolException: A response was received from a one-way send over the underlying IRequestChannel. Make sure the remote endpoint has a compatible binding at its endpoint (one that contains OneWayBindingElement). Server stack trace: at System.ServiceModel.Channels.RequestOneWayChannelFactory.RequestOutputChannel.ValidateResponse(Message response) at System.ServiceModel.Channels.RequestOneWayChannelFactory.RequestOutputChannel.OnSend(Message message, TimeSpan timeout) at System.ServiceModel.Channels.OutputChannel.Send(Message message, TimeSpan timeout) It's fairly easy to figure out what happened from the message and stack trace although it may not be obvious why. Inside the OneWay channel, there is validation that the system is truly acting in a one-way fashion. If you look at the code for the ValidateResponse method, you would see that it is essentially checking that the response message is null. In this case, we got a reply back from the server even though we were not expecting it to send anything back. Remember, the server knows nothing about WCF and behaves exactly the same for every request regardless Read More...

Copyright © 2006 Microsoft Corporation. All Rights Reserved. | Terms of Use | Privacy Statement | Contact Us