使用Savon SOAP客户端的API调用结果在EndpointDispatcher错误的ContractFilter不匹配

时间:2012-01-26 00:20:42

标签: ruby gem savon

我遇到了Savon Ruby Gem生成失败的SOAP API调用的问题,但是当我将完全相同的XML消息复制并粘贴到SOAP-UI中时,它成功了。

我发送此消息:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tem="http://tempuri.org/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:vis="http://schemas.datacontract.org/2004/07/Vision.SecureOriginCommand.ServiceContracts">
<soapenv:Body>
  <tem:CameraConfiguration>
  <tem:request>
   <vis:ClientToken>5555</vis:ClientToken>
   <vis:DeviceID>26219</vis:DeviceID>
    <vis:Enabled>1</vis:Enabled>
    <vis:Interval>60</vis:Interval>
  </tem:request>
 </tem:CameraConfiguration>
</soapenv:Body>

此API(远程网络摄像头配置): https://oapqa.onasset.com/Services/SecureOriginCommand.svc?wsdl

但它失败了这条消息:

 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 'oapSetSentryReportingIntervalRequest' 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>

我的第一个想法是我必须在动作名称中输入错字。但 不,当我在SOAP-UI中尝试完全相同的消息时,我得到以下内容 成功:

  <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body>
  <CameraConfigurationResponse xmlns="http://tempuri.org/">
     <CameraConfigurationResult xmlns:a="http://schemas.datacontract.org/2004/07/Vision.SecureOriginCommand.ServiceContracts" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
        <a:Error/>
        <a:Result>true</a:Result>
     </CameraConfigurationResult>
  </CameraConfigurationResponse>
 </s:Body>
</s:Envelope>

这让我相信问题不是由格式引起的 我的xml消息,但我正在配置我的客户端。这是实际的代码:

Savon.configure do |config|
 config.log = :debug
 config.env_namespace = :soapenv
 config.raise_errors = false
end

# TODO Enable ssl certficate verification
client = Savon::Client.new do
  wsdl.document = TARGET_SO_WSDL
  http.auth.ssl.verify_mode = :none
end

resp = client.request 'tem', 'CameraConfiguration' do
  soap.namespaces['xmlns:vis'] = 'http://schemas.datacontract.org/2004/07/Vision.SecureOriginCommand.ServiceContracts'
  soap.namespaces['xmlns:tem'] = 'http://tempuri.org/'
  soap.body = {
    'tem:request' => {
      'vis:ClientToken' => ON_ASSET_API_KEY,
      'vis:DeviceID' => webcam.gps_device.device_id,
      'vis:Enabled' => 1, 
      'vis:Interval' => webcam.report_interval
    }
  }
end

我已经与维护我正在尝试的API的开发人员交谈过 访问。我认为他的回答可以提供一个线索:

Binding on the RemoteSentryService was set to mexHttpBinding instead of mexHttpsBinding.


I don’t think this should give you a fault exception, because its working  on .NET simulator client I have. And this endpoint is only used to generate the wsdl (MetaExchange Binding). But, given you are using a different client, I would still give it a shot.

I also regenerated the proxy from wsdl and updated my sample simulator and it looks good.

此问题是Savon和Microsoft SOAP的已知问题 端点还是HTTPS?或者这个问题只是我遇到的问题?

1 个答案:

答案 0 :(得分:5)

调试它并注意到Savon遗憾的是没有发送正确的SOAPAction HTTP头。仅供参考:通过soapUI发送SOAP请求后,您可以单击“RAW”选项卡(在请求窗口中垂直对齐)进一步调查。

以下是完整的示例:

client = Savon::Client.new do
  wsdl.document = TARGET_SO_WSDL
  http.auth.ssl.verify_mode = :none
end

resp = client.request 'tem', 'CameraConfiguration' do
  # Notice, that the SOAPAction needs to the wrapped in double quotes:
  http.headers['SOAPAction'] = %("http://tempuri.org/ISecureOriginCommand/CameraConfiguration")
  soap.namespaces['xmlns:vis'] = 'http://schemas.datacontract.org/2004/07/Vision.SecureOriginCommand.ServiceContracts'
  soap.body = {
    'tem:request' => {
      'vis:ClientToken' => 5555,
      'vis:DeviceID' => 26219,
      'vis:Enabled' => 1, 
      'vis:Interval' => 60
    }
  }
end

希望它适合你!