使用Savon在Ruby on Rails中调用SOAP在包络和主操作方面变得奇怪

在使用Savon.rb的rails项目中,我试图进行一个非常复杂的SOAP调用。 至少复杂到Savon构建器的扩展很麻烦所以我决定直接操作:xml。

首先我发起客户:

@client = Savon.client( :endpoint => 'https://testservice.postnl.com/CIF_SB/BarcodeWebService/1_1/BarcodeWebService.svc', :wsdl => 'https://testservice.postnl.com/CIF_SB/BarcodeWebService/1_1/?wsdl') 

然后我打电话的形状为:

 @request = @client.build_request(:generate_barcode, xml: %Q{ ... see soap call (with ruby interpolation) ... } 

我添加了一个格式正确的l Time.now, format: :postnl_api字符串,其余的仍然是硬编码的。 包括消息号。

以下是Savon在这种情况下实际调用的方式,如使用@request.body检索的。

我的应用程序中的SOAP调用

    http://postnl.nl/cif/services/BarcodeWebService/IBarcodeWebService/GenerateBarcode    devc_!R4xc8p9 xxxxxxxx       DEVC 11223344   3S DEVC 1000000-2000000     

接下来是一个调用应该如何看待,因为我看到这个调用在公司的沙箱环境中取得了成功。

应该是SOAP调用

   http://postnl.nl/cif/services/BarcodeWebService/IBarcodeWebService/GenerateBarcode   devc_!R4xc8p9 xxxxxxxx       5 28-06-2017 14:15:41   DEVC 11223344   3S DEVC 1000000-2000000     

似乎关闭的主要事情(这也是使用Savon builder btw的情况)是envelope的属性和主要操作:generate_barcode形状及其属性。 我不明白为什么我在GenerateBarcode之前获得前缀wsdl:

我告诉Savon拿走我的xml然后就像那样构建它,但它不起作用。 按原样发送我的版本将返回错误400

编辑使用克里斯他的部分

使用@Chris他的回答我能够进行以下调用:

设置通话

 @client = Savon.client( :endpoint => 'https://testservice.postnl.com/CIF_SB/BarcodeWebService/1_1/BarcodeWebService.svc', :wsdl => 'https://testservice.postnl.com/CIF_SB/BarcodeWebService/1_1/?wsdl', :log => true, :wsse_auth => [ENV['postnl_username'], ENV['postnl_password']], :pretty_print_xml => true, :convert_request_keys_to => :camelcase, :env_namespace => :s) message = { "d6p1:Message" => { "d6p1:MessageID" => "7", "d6p1:MessageTimeStamp" => I18n.l( Time.now, format: :postnl_api) }, "d6p1:Customer" => { "d6p1:CustomerCode" => "DEVC", "d6p1:CustomerNumber" => "11223344"}, "d6p1:Barcode" => { "d6p1:Type" => "3S", "d6p1:Range" => "DEVC", "d6p1:Serie" => "1000000-2000000" } } @client.call(:generate_barcode, :message => message, :soap_header => { "Action" => "http://postnl.nl/cif/services/BarcodeWebService/IBarcodeWebService/GenerateBarcode"}) 

呼叫

    http://postnl.nl/cif/services/BarcodeWebService/IBarcodeWebService/GenerateBarcode   devc_!R4xc8p9 098fd559930983af31ef6630a0bb0c1974156561       7 17-07-2017 22:13:35   DEVC 11223344   3S DEVC 1000000-2000000     

回应

     a:InternalServiceFault The server was unable to process the request due to an internal error. For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the <serviceDebug> configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework SDK documentation and inspect the server trace logs.    

好的,这有效(已validation)

 @client = Savon.client( :wsdl => 'https://testservice.postnl.com/CIF_SB/BarcodeWebService/1_1/?wsdl', :log => true, :wsse_auth => ['devc_!R4xc8p9', 'xxx'], :pretty_print_xml => true, :convert_request_keys_to => :camelcase, :env_namespace => :s, :namespace_identifier => nil ) message = { "d6p1:Message" => { "d6p1:MessageID" => "10", "d6p1:MessageTimeStamp" => Time.now.strftime("%d-%m-%Y %H:%M:%S") }, "d6p1:Customer" => { "d6p1:CustomerCode" => "DEVC", "d6p1:CustomerNumber" => "11223344"}, "d6p1:Barcode" => { "d6p1:Type" => "3S", "d6p1:Range" => "DEVC", "d6p1:Serie" => "1000000-2000000" } } attributes = { "xmlns:d6p1" => "http://postnl.nl/cif/domain/BarcodeWebService/", "xmlns:i" => "http://www.w3.org/2001/XMLSchema-instance", "xmlns" => "http://postnl.nl/cif/services/BarcodeWebService/"} @client.call(:generate_barcode, :attributes => attributes, :message => message, :soap_header => { "Action" => "http://postnl.nl/cif/services/BarcodeWebService/IBarcodeWebService/GenerateBarcode"}) 

所以诀窍是添加:namespace_identifier => nil和发送attributes 。 设置namespace_identifier从GenerateBarcode删除wsdl ,ans属性在GenerateBarcode标记上设置一些名称空间。 现在我记得为什么我这么讨厌SOAP 🙁