4

我遇到了一个问题,即 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 的已知问题吗?还是这个问题只有我遇到?

4

1 回答 1

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

希望对你有帮助!

于 2012-01-26T09:31:08.020 回答