我有一个很好的任务,就是使用带有Rails的大量SOAP api。 SOAP服务有三种不同的绑定; wsHttpBinding,wsHttpBinding与x509,以及自定义绑定。我只能使用wsHttpBinding来击中两个端点,但第三个端点需要用户名和密码,但不能使用它。我因为证书而避免使用x509,并且自定义绑定在SoapUI中运行良好,但是使用Savon我得到以下错误。
带有操作的消息''由于EndpointDispatcher上的ContractFilter不匹配,无法在接收方处理。这可能是由于合同不匹配(发送方与接收方之间的操作不匹配)或发送方与接收方之间的绑定/安全性不匹配。检查发件人和收件人是否具有相同的合同和相同的约束(包括安全要求,例如邮件,传输,无)。
我已经使用了Savon生成的确切XML并将其放入SoapUI中并且可以正常工作。
这可能是一个有约束力的问题吗?有没有办法告诉它使用这个自定义绑定?
以下是我在App.config
中找到的自定义绑定<bindings>
<customBinding>
<binding name="cust">
<textMessageEncoding messageVersion="Soap12" />
<httpTransport />
</binding>
<binding name="cust1">
<textMessageEncoding messageVersion="Soap12" />
<httpTransport />
</binding>
<binding name="cust2">
<textMessageEncoding messageVersion="Soap12" />
<httpTransport />
</binding>
</customBinding>
</bindings>
<endpoint address="http://api.xyz.com/stuff.svc/cust"
binding="customBinding" bindingConfiguration="cust" contract="stuff.Xstuff"
name="cust" />
编辑#1
这是我当前的客户端设置,这有助于它。
@client = Savon.client(
wsdl: 'http://api.xyz.com/stuff.svc?wsdl',
wsse_auth: %w'username password',
wsse_timestamp: true,
raise_errors: false,
log: true,
log_level: :debug,
soap_version: 2,
pretty_print_xml: true,
convert_request_keys_to: :none,
use_wsa_headers: true,
headers: {'Content-Type' => 'application/soap+xml; charset=utf-8'}
编辑#2
我发现了这个问题。 Savon没有像SoapUI那样在Content-Type中设置动作。感谢@RicardoPontual建议再次尝试比较Savon和SoapUI请求,这让我更仔细地看一下并注意到这个问题。
headers: {'Content-Type' => 'application/soap+xml;charset=UTF-8;action="tempuri.org/stuff/set_table_stuff"'}
答案 0 :(得分:2)
您需要在 Content-Type 标头中设置action="tempuri.org/stuff/set_table_stuff"'
,如下所示:
@client = Savon.client(
wsdl: 'http://api.xyz.com/stuff.svc?wsdl',
wsse_auth: %w'username password',
wsse_timestamp: true,
raise_errors: false,
log: true,
log_level: :debug,
soap_version: 2,
pretty_print_xml: true,
convert_request_keys_to: :none,
use_wsa_headers: true,
headers: {'Content-Type' => 'application/soap+xml; charset=UTF-8; action="tempuri.org/stuff/set_table_stuff";'}
答案 1 :(得分:1)
根据我们在评论中谈到的内容,添加标题以及您想要使用的操作的操作可以解决问题,如下所示:
@client = Savon.client(
wsdl: 'http://api.xyz.com/stuff.svc?wsdl',
wsse_auth: %w'username password',
wsse_timestamp: true,
raise_errors: false,
log: true,
log_level: :debug,
soap_version: 2,
pretty_print_xml: true,
convert_request_keys_to: :none,
use_wsa_headers: true,
headers: {'Content-Type' => 'application/soap+xml;charset=UTF-8;action="tempuri.org/stuff/set_table_stuff"'}
);