none
WS-Addressing - accepting HTTP 202 return code RRS feed

  • Question

  • Dear all,

    my web servcies client ends with following error when using WS-Addressing. I thing, that problem is HTTP 202 response code with emtpy body, while .NET client expects some response. but my goal is to process response in another aplication (service) and require ws client not to expect any response back.

    How to do it ?

    Unhandled Exception: System.ServiceModel.CommunicationException: The server did not provide a meaningful reply; this might be caused
     by a contract mismatch, a premature session shutdown or an internal server error.
    
    Server stack trace:
       at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins,
     Object[] outs, TimeSpan timeout)
       at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
    
       at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
    
    Exception rethrown at [0]:
       at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
       at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
       at ConsoleApplication2.ServiceReference1.HelloWorld.hello(helloRequest request)
       at ConsoleApplication2.ServiceReference1.HelloWorldClient.ConsoleApplication2.ServiceReference1.HelloWorld.hello(helloRequest req
    uest) in c:\Users\tjech\Documents\Visual Studio 2012\Projects\ConsoleApplication2\Service References\ServiceReference1\Reference.cs:
    line 120
       at ConsoleApplication2.ServiceReference1.HelloWorldClient.hello(String arg0) in c:\Users\tjech\Documents\Visual Studio 2012\Proje
    cts\ConsoleApplication2\Service References\ServiceReference1\Reference.cs:line 127
       at ConsoleApplication2.Program.Main(String[] args) in c:\Users\tjech\Documents\Visual Studio 2012\Projects\ConsoleApplication2\Pr
    ogram.cs:line 25

    Here is a TCP communication :

    Request:

    POST /helloworld/HelloWorldService HTTP/1.1 Content-Type: text/xml; charset=utf-8 SOAPAction: "http://sample/hello/input" Host: ntjech2:7800 Content-Length: 679 Expect: 100-continue Connection: Keep-Alive <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:a="http://www.w3.org/2005/08/addressing">

    <s:Header><a:Action s:mustUnderstand="1">http://sample/hello/input</a:Action><a:MessageID>urn:uuid:7f9a0be2-464a

    -4fb8-b2cc-2440a77eb20c</a:MessageID><a:ReplyTo><a:Address>http://172.17.12.23:8091/helloworld/Callback</a:Addres

    s></a:ReplyTo><a:FaultTo><a:Address>http://172.17.12.23:8091/helloworld/Callback</a:Address></a:FaultTo><a:To s:m

    ustUnderstand="1">http://ntjech2:7800/helloworld/HelloWorldService</a:To></s:Header><s:Body><hello xmlns="http://

    sample/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><arg0 xmlns="">.NET</arg0></hello></s:Body></s:Envelo

    pe>


    Response :

    HTTP/1.1 100 Continue
    
    HTTP/1.1 202 Accepted
    WMB-Ack-Type: WMB-Reply-Ack
    WMB-Ack-Timing: WMB-Early-Ack
    Content-Length: 0
    Date: Fri, 08 Feb 2013 13:29:58 GMT
    Server: Apache-Coyote/1.1


    The client code :

    using System.ServiceModel.Dispatcher;
    
    namespace ConsoleApplication2
    {
        class Program
        {
            static void Main(string[] args)
            {
                
                ConsoleApplication2.ServiceReference1.HelloWorldClient c = new ConsoleApplication2.ServiceReference1.HelloWorldClient();
                c.Endpoint.Address = new EndpointAddress("http://ntjech2:7800/helloworld/HelloWorldService");
                c.Endpoint.Behaviors.Add(new
                MessageHeaderBehavior("http://172.17.12.23:8091/helloworld/Callback", "http://172.17.12.23:8091/helloworld/Callback"));
                string ret = c.hello(".NET");
                Console.WriteLine("ret = {0}", ret);
            }
        }
    

    ReplyTo and FaultTo endpoint is overided here :

    class MessageHeaderInspector : IClientMessageInspector, IDispatchMessageInspector
        {
    
            private string replyTo;
            private string faultTo;
    
            public MessageHeaderInspector(string replyTo, string faultTo)
            {
                this.replyTo = replyTo;
                this.faultTo = faultTo;
    
            }
    
            object IClientMessageInspector.BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
            {
                Console.WriteLine("called");
                request.Headers.ReplyTo = new EndpointAddress(replyTo);
                request.Headers.FaultTo = new EndpointAddress(faultTo);
                return null;
            }
            object IDispatchMessageInspector.AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext)
            {
                return null;
            }
            void IDispatchMessageInspector.BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
            { 
            }
            void IClientMessageInspector.AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
            {
            }
        }
    
        public class MessageHeaderBehavior : IEndpointBehavior
        {
            private string replyTo;
            private string faultTo;
    
            public MessageHeaderBehavior(string replyTo, string faultTo)
            {
                this.replyTo = replyTo;
                this.faultTo = faultTo;
            }
            #region IEndpointBehavior Members
    
            public void AddBindingParameters(ServiceEndpoint endpoint,
               System.ServiceModel.Channels.BindingParameterCollection
                                                    bindingParameters)
            {
            }
    
            public void ApplyClientBehavior(ServiceEndpoint endpoint,
                    System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
            {
                MessageHeaderInspector inspector =
                   new MessageHeaderInspector(replyTo, faultTo);
                clientRuntime.MessageInspectors.Add(inspector);
            }
    
            public void ApplyDispatchBehavior(ServiceEndpoint endpoint,
                 System.ServiceModel.Dispatcher.EndpointDispatcher
                                                  endpointDispatcher)
            {
            }
    
            public void Validate(ServiceEndpoint endpoint)
            {
            }
    
            #endregion
        }
    }
    

    WSDL of the service :

    <definitions targetNamespace="http://sample/" name="HelloWorldService">

    <wsp:Policy wsu:Id="HelloWorldPortBinding_Wsaw_Addressing_Policy-HelloWorldPortBinding_WSAM_Addressing_Policy-HelloWorldPortBinding_WSAM_Addressing_Policy">

    <wsapw3c:UsingAddressing wsp:Optional="true"/><wsam:Addressing wsp:Optional="true"><wsp:Policy/>

    </wsam:Addressing></wsp:Policy><types>

    <xsd:schema><xsd:import namespace="http://sample/" schemaLocation="http://ntjech2:8090/helloworld/HelloWorldService?xsd=1"/></xsd:schema>

    </types>

    <message name="hello">

    <part name="parameters" element="tns:hello"/>

    </message><message name="helloResponse">

    <part name="parameters" element="tns:helloResponse"/>

    </message>

    <portType name="HelloWorld">

    <operation name="hello">

    <input wsaw:Action="http://sample/hello/input" wsam:Action="http://sample/hello/input" message="tns:hello"/>

    <output wsaw:Action="http://sample/hello/output" wsam:Action="http://sample/hello/output" message="tns:helloResponse"/>

    </operation>

    </portType>

    <binding name="HelloWorldPortBinding" type="tns:HelloWorld"><wsaw:UsingAddressing/>

    <wsp:PolicyReference URI="#HelloWorldPortBinding_Wsaw_Addressing_Policy-HelloWorldPortBinding_WSAM_Addressing_Policy-HelloWorldPortBinding_WSAM_Addressing_Policy"/>

    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>

    <operation name="hello">

    <soap:operation soapAction=""/>

    <input><soap:body use="literal"/>

    </input><output><soap:body use="literal"/>

    </output>

    </operation>

    </binding>

    <service name="HelloWorldService">

    <port name="HelloWorldPort" binding="tns:HelloWorldPortBinding">

    <soap:address location="http://ntjech2:8090/helloworld/HelloWorldService"/>

    </port>

    </service>

    </definitions>


    Regards

    Tomas

    Friday, February 8, 2013 1:56 PM

Answers