Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么是;wsdl";在使用savon进行ruby soap通信时,命名空间被插入到操作名中?_Ruby_Soap_Savon - Fatal编程技术网

为什么是;wsdl";在使用savon进行ruby soap通信时,命名空间被插入到操作名中?

为什么是;wsdl";在使用savon进行ruby soap通信时,命名空间被插入到操作名中?,ruby,soap,savon,Ruby,Soap,Savon,我正在尝试访问一个我无法控制的SOAP服务。其中一个操作称为ProcessMessage。我按照这个示例生成了一个SOAP请求,但是我得到了一个错误,说该操作不存在。我将问题追溯到信封主体的生成方式 <env:Envelope ... "> <env:Header> <wsse:Security ... "> <wsse:UsernameToken ..."> <

我正在尝试访问一个我无法控制的SOAP服务。其中一个操作称为
ProcessMessage
。我按照这个示例生成了一个SOAP请求,但是我得到了一个错误,说该操作不存在。我将问题追溯到信封主体的生成方式

<env:Envelope ... ">
    <env:Header>
        <wsse:Security ... ">
            <wsse:UsernameToken ...">
                <wsse:Username>USER</wsse:Username>
                    <wsse:Nonce>658e702d5feff1777a6c741847239eb5d6d86e48</wsse:Nonce>
                    <wsu:Created>2010-02-18T02:05:25Z</wsu:Created>
                    <wsse:Password ... >password</wsse:Password>
            </wsse:UsernameToken>
        </wsse:Security>
    </env:Header>
    <env:Body>
        <wsdl:ProcessMessage>
            <payload>
                ......
            </payload>
        </wsdl:ProcessMessage>
    </env:Body>
</env:Envelope>     
当它由示例Java应用程序生成时,它就是这样,并且可以正常工作。该标记是我的Ruby应用程序生成的内容与示例Java应用程序之间的唯一区别。有没有办法摆脱
“wsdl:“
名称空间在一个标记前面,并添加一个这样的属性。除此之外,有没有一种方法可以像身体的其他部分一样,强制动作不通过作为字符串传递来生成

这是我的密码:

require 'rubygems'
require 'savon'
client = Savon::Client.new "https://gmservices.pp.gm.com/ProcessMessage?wsdl"

response = client.process_message! do | soap, wsse |
wsse.username = "USER"
wsse.password = "password"
soap.namespace = "http://www.starstandards.org/webservices/2005/10/transport" #makes no difference
soap.action = "ProcessMessage" #makes no difference
soap.input = "ProcessMessage" #makes no difference

#my body at this point is jsut one big xml string

soap.body = "<payload>...</payload>" 
# putting <ProccessMessage> tag here doesn't help as it just creates a duplicate tag in the body, since Savon keeps interjecting  <wsdl:ProcessMessage> tag.

  end
需要“rubygems”
需要“savon”
client=Savon::client.new“https://gmservices.pp.gm.com/ProcessMessage?wsdl"
响应=client.process\u消息!do | soap,wsse|
wsse.username=“用户”
wsse.password=“password”
soap.namespace=”http://www.starstandards.org/webservices/2005/10/transport“#没什么区别
soap.action=“ProcessMessage”没有区别
soap.input=“ProcessMessage”#没有区别
#此时我的主体是jsut一个大xml字符串
soap.body=“…”
#把标签放在这里并没有帮助,因为它只是在身体中创建了一个重复的标签,因为Savon一直在插入标签。
结束

我尝试了handsoap,但它不支持HTTPS,而且令人困惑。我尝试了soap4r,但它比handsoap更令人困惑。

您需要向soap传递一个数组。输入第二个元素是包含名称空间详细信息的哈希

soap.input = [ 
  "ProcessMessage", 
  {"xmlns" => "http://www.starstandards.org/webservices/2005/10/transport"}
]
这将确保最终将名称空间声明作为主元素的属性

您可能还将在元素前面声明一个名称空间,如下所示

<env:Body>
    <wsdl:ProcessMessage xmlns="........." >
        <payload>
            ......
        </payload>
    </wsdl:ProcessMessage>
</env:Body>

......

但这对我来说不是问题,问题在于缺少namespace属性,而不是元素前面是否存在名称空间。

Steve,您看到了wsdl:在ProcessMessage标记前面吗?-我认为这是唯一让我感到不快的事情,但事实并非如此(顺便说一句,在Savon lib的第160行的soap.rb中它是硬设置的)。即使我没有在soap.namespace中指定它,它也很难生成并附加到最终的xml中。这是我的服务不允许的

虽然生成的xml是一个有效的xml,但根据我试图与之交谈的服务的要求,它并不完整。即:在生成的xml中

<?xml version="1.0" encoding="UTF-8"?>
这终于奏效了


我将向rubii建议这一点——如果这个选项可用,它将解决许多罕见的情况——人们可以生成自定义xml并使用savon库的其余部分

对于我的web服务,我需要在Steve的解决方案之上去掉
“wsdl”
名称空间

使用Savon 0.9.6进行测试:

client = Savon::Client.new "https://example.com/webservice/account.asmx?WSDL"
response = client.request "GetAccount" do
  # Gotcha 1: set default namespace for body elements
  soap.input = ["GetAccount", {"xmlns" => "https://example.com/webservice/"}]
  soap.body = {
    "AccountID" => 1234
  }
  # Gotcha 2: get rid of namespace declaration of body elements
  soap.element_form_default = :unqualified
  # Gotcha 3: set SOAPAction different from default
  http.headers["SOAPAction"] = '"https://example.com/webservice/GetAccount"'
end

我花了几个小时试图找到一个解决方案来摆脱:

<wsdl:ProcessMessage>
</wsdl:ProcessMessage>

在Savon 2进行了测试。

这张票在以下位置打开:嗨,尼克,我看到了同样的问题,你有什么进展吗?嗨,史蒂夫。我把项目的这一部分放在等待状态,因为还有其他更重要的功能需要实现,这是一个“很好拥有”的列表。今天晚些时候我会尝试你的解决方案,看看是否有效。谢谢你让我知道你!史提夫。谢谢你的留言-这不是我的解决方案,但它让我更仔细地思考和查看日志。看看我自己的答案。评论中没有足够的空间。:-)谢谢你的解决方案在我遇到同样的问题时很有魅力。你的解决方案对我很有效。我错过了行动中的xmlns!我仍然在主体中获得wsdl:namespace,但它不会影响SOAP请求。我认为这是一个很好的解决方案。我发现IIS/.net抱怨缺少名称空间,但并不关心文件顶部是否有指令。祝你好运,到那一步是相当痛苦的。
client = Savon::Client.new "https://example.com/webservice/account.asmx?WSDL"
response = client.request "GetAccount" do
  # Gotcha 1: set default namespace for body elements
  soap.input = ["GetAccount", {"xmlns" => "https://example.com/webservice/"}]
  soap.body = {
    "AccountID" => 1234
  }
  # Gotcha 2: get rid of namespace declaration of body elements
  soap.element_form_default = :unqualified
  # Gotcha 3: set SOAPAction different from default
  http.headers["SOAPAction"] = '"https://example.com/webservice/GetAccount"'
end
<wsdl:ProcessMessage>
</wsdl:ProcessMessage>
client = Savon.client(
 :no_message_tag => true
)