开发者

Can't get Savon to form the right XML

I've used SOAP before but many, many years ago and try to stay clear if I can help it.

Short story...

  • Using "Soap Client" OS X app I can get the response I wish.
  • If I use client.request :foo_web_serivce, :language_count, :body => { :foo_app_id => "...", :session_id => "..." } then I get a Status 200 but my results are -1 as I believe the app_id is not recognised.
  • If I try to replicate the Soap Client call (<LanguageCount>) rather than Savon's call (<foo_web_service:LanguageCount>) then I get an Status 500.

Please advise and thanks in advance.

Long Story...

Using SOAP Client I can see that the correct request XML is:

User-Agent: Mac OS X; WebServicesCore (357)
Content-Type: text/xml
Host: redacted
Soapaction: http://tempuri.org/redacted/LanguageCount

<?xml v开发者_高级运维ersion="1.0" encoding="utf-8"?>
  <SOAP-ENV:Envelope
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
    SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
      <SOAP-ENV:Body>
        <LanguageCount xmlns="http://tempuri.org/">
          <fooAppID xsi:type="xsd:string">12345678-1234-1234-1234-123456789123</fooAppID>
          <sessionID xsi:type="xsd:string">12345678-1234-1234-1234-123456789123</sessionID>
        </LanguageCount>
      </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>

However, when I try to do it in the console like so:

ruby-1.8.7-p302 > client = Savon::Client.new do |wsdl, http, wsse|
ruby-1.8.7-p302 >       wsdl.document = "http://FooService.cloudapp.net/FooService.svc?wsdl"
ruby-1.8.7-p302 ?>  end
 => #<Savon::Client:0x1055e2dc8 @http=#<HTTPI::Request:0x1055e2bc0>, @wsse=#<Savon::WSSE:0x1055e2b98>, @wsdl=#<Savon::WSDL::Document:0x1055e2c10 @request=#<HTTPI::Request:0x1055e2bc0>, @document="http://FooService.cloudapp.net/FooService.svc?wsdl">> 
ruby-1.8.7-p302 > 
ruby-1.8.7-p302 >   client.request :language_count, :body => {:Foo_app_id => "12345678-1234-1234-1234-123456789123", :session_id => "12345678-1234-1234-1234-123456789123"}
Retrieving WSDL from: http://FooService.cloudapp.net/FooService.svc?wsdl
HTTPI executes HTTP GET using the net_http adapter
SOAP request: http://Fooservice.cloudapp.net/FooService.svc
SOAPAction: "LanguageCount", Content-Type: text/xml;charset=UTF-8
<?xml version="1.0" encoding="UTF-8"?><env:Envelope xmlns:wsdl="http://tempuri.org/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"><env:Body><LanguageCount><FooAppId>12345678-1234-1234-1234-123456789123</FooAppId><sessionId>12345678-1234-1234-1234-123456789123</sessionId></LanguageCount></env:Body></env:Envelope>
HTTPI executes HTTP POST using the net_http adapter
SOAP response (status 500):
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><s:Fault><faultcode xmlns:a="http://schemas.microsoft.com/ws/2005/05/addressing/none">a:ActionNotSupported</faultcode><faultstring xml:lang="en-US">The message with Action 'LanguageCount' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver.  Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None).</faultstring></s:Fault></s:Body></s:Envelope>
Savon::SOAP::Fault: (a:ActionNotSupported) The message with Action 'LanguageCount' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver.  Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None).

But when I use the namespace of foo_web_service, I get:

 ruby-1.8.7-p302 > client = Savon::Client.new do |wsdl, http, wsse| ruby-1.8.7-p302 >       wsdl.document = "http://FooService.cloudapp.net/FooService.svc?wsdl" ruby-1.8.7-p302 ?>  end  =>
#<Savon::Client:0x105882498 @http=#<HTTPI::Request:0x105882358>, @wsse=#<Savon::WSSE:0x105882330>, @wsdl=#<Savon::WSDL::Document:0x105882380 @request=#<HTTPI::Request:0x105882358>, @document="http://FooService.cloudapp.net/FooService.svc?wsdl">> ruby-1.8.7-p302 >  ruby-1.8.7-p302 >   client.request :Foo_web_service, :language_count, :body => {:Foo_app_id
=> "12345678-1234-1234-1234-123456789123", :session_id => "12345678-1234-1234-1234-123456789123"} Retrieving WSDL from: http://FooService.cloudapp.net/FooService.svc?wsdl HTTPI executes HTTP GET using the net_http adapter SOAP request: http://Fooservice.cloudapp.net/FooService.svc SOAPAction: "http://tempuri.org/FooService/LanguageCount", Content-Type: text/xml;charset=UTF-8 <?xml version="1.0" encoding="UTF-8"?><env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:Foo_web_service="http://tempuri.org/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"><env:Body><Foo_web_service:LanguageCount><FooAppId>12345678-1234-1234-1234-123456789123</FooAppId><sessionId>12345678-1234-1234-1234-123456789123</sessionId></Foo_web_service:LanguageCount></env:Body></env:Envelope> HTTPI executes HTTP POST using the net_http adapter SOAP response (status 200): <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><LanguageCountResponse xmlns="http://tempuri.org/"><LanguageCountResult>-1</LanguageCountResult></LanguageCountResponse></s:Body></s:Envelope>
=> #<Savon::SOAP::Response:0x105a2cca8 @http=#<HTTPI::Response:0x105a28ce8 @body="<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><LanguageCountResponse xmlns=\"http://tempuri.org/\"><LanguageCountResult>-1</LanguageCountResult></LanguageCountResponse></s:Body></s:Envelope>", @raw_body="<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><LanguageCountResponse xmlns=\"http://tempuri.org/\"><LanguageCountResult>-1</LanguageCountResult></LanguageCountResponse></s:Body></s:Envelope>", @code=200, @headers={"x-powered-by"=>"ASP.NET", "x-aspnet-version"=>"4.0.30319", "content-type"=>"text/xml; charset=utf-8", "date"=>"Sat, 02 Jul 2011 23:40:56 GMT", "server"=>"Microsoft-IIS/7.0", "content-length"=>"214", "cache-control"=>"private"}>, @soap_fault=Savon::SOAP::Fault, @http_error=Savon::HTTP::Error>  ruby-1.8.7-p302 >


Long story short, I had to make 3 changes.

  1. Changed response = client.request :language_count to response = client.request "LanguageCount"
  2. Added :xmlns => "http://tempuri.org/" to the end of the client.request call
  3. Explicitly called the SOAPaction like: client.http.headers["SOAPAction"] = '"http://tempuri.org/FooService/LanguageCount"'

Hope this helps someone as I've been in SOAP hell for the weekend and hopefully I'll stop someone else being there.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜