PHP消费WCF SSL SOAP客户端1.2。

3

我在使用PHP消费wsHttpBinding WCF时遇到了一些问题。最初我尝试使用SOAP1.2,但无法指定WS Action。

我下载了nusoap库。最初我收到一个错误,说由于类型不匹配(text/xml而不是预期的application/soap+xml),webservice无法接受数据。我成功地对nusoap.php进行了更改,以将数据发送为application/soap+xml。现在不再抛出错误,但服务器返回400错误请求。

我可以从WCFTestClient和SOAPUI中使用服务而无需任何麻烦,但无法从PHP中使用它。我甚至复制了SOAPUI中的整个soap信封,并将nusoap.php中的$soapmsg设置为完全相同,但仍然失败。

所以有人想提供一些指导吗?

编辑 这是我在SOAP 1.2中尝试的代码

$params  = array("soap_version"=> SOAP_1_2,
                "trace"=>1,
                "exceptions"=>0,
                );

$client = @new SoapClient('https://localhost/wcftest/Service.svc?wsdl',$params);

$retval = $client->GetData(array('value'=>'stuff'));
if (is_soap_fault($retval)) {
    trigger_error("SOAP Fault: (faultcode: {$retval->faultcode}, faultstring: {$retval->faultstring})", E_USER_ERROR);
}

编辑 #2 以下是在SOAPUI之外可行的代码

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:tem="http://tempuri.org/">
   <soap:Header xmlns:wsa="http://www.w3.org/2005/08/addressing"><wsa:Action>http://tempuri.org/IService/GetData</wsa:Action></soap:Header>
   <soap:Body>
      <tem:GetData>
         <!--Optional:-->
         <tem:value>stuff</tem:value>
      </tem:GetData>
   </soap:Body>
</soap:Envelope>

在根据Gords下面的链接手动添加了SoapHeaders之后,当我在Netbeans中进行调试时,得到这个作为__last_request的内容,并且仍然存在相同的错误。
    "<?xml version="1.0" encoding="UTF-8"?>
    <env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="http://tempuri.org/">
<env:Header>
<ns1:Action>http://tempuri.org/IService/GetData</ns1:Action>
</env:Header>
<env:Body><ns1:GetData><ns1:value>stuff</ns1:value></ns1:GetData></env:Body></env:Envelope>

有什么建议吗?

谢谢! 安迪


2
如果你正在使用PHP5,你尝试过PHP内置的SOAP支持吗?我曾经维护过一个基于ASP.NET的Web服务,可以使用PHP5的SOAP实现进行调用,但无法从NuSOAP进行调用。(如果我没记错,这与将参数作为对象传递给Web服务有关,这是NuSOAP显然无法做到的。) - Gord Thompson
嗨,Gord。感谢您的回复。当我使用SOAP_CLIENT(而不是Nusoap_client)时,我会不断收到错误消息:“消息中指定的SOAP操作''与HTTP SOAP操作'http://tempuri.org/IService/GetData'不匹配。”这是我转向nusoap的原因之一。 - Andrew MacNaughton
1
你提到了SOAP_1.2,但尝试使用过WSDL吗?就我记得(那是几年前的事了),这是我发现的唯一能让PHP与该Web服务进行交互的方法。我尝试深入了解它的几次,但因为微软文档都是关于从.NET应用程序中使用ASP.NET Web服务,而我能找到的大多数PHP参考资料(博客等)似乎并不十分支持与微软相关的任何内容,所以我陷入了困境。:( - Gord Thompson
嗨,Gord。我已更新原始帖并附上了我用于1.2版本的代码。完全同意,在php和MS工具之间实现互操作性是一场噩梦! - Andrew MacNaughton
1
我找到了我的旧示例代码,它看起来非常类似于你的,所以我可能无法为此提供“万能解决方案”。:( 你是否碰巧看到了Stack Overflow文章这里 - Gord Thompson
嗨Gord,谢谢你的回复。我之前已经检查过了,但看起来这可能是一个可行的解决方案。 - Andrew MacNaughton
1个回答

6

好的,我已经把这个问题解决了。感谢Gord让我重新检查之前忽略的东西。

我最终放弃了nusoap,只使用SOAP 1.2。以下是我的php代码:

//Declare some paramaters for our soapclient. Need to make sure its set to soap 1.2
$params  = array("soap_version"=> SOAP_1_2,
                "trace"=>1,
                "exceptions"=>0,
                );

//Create the soap client
$client = new SoapClient('https://localhost/wcftest/Service.svc?wsdl',$params);
//add some WSAddressing Headers in. Ensure that you have the Namespace as the address if you are using wsHttpBinding on the endpoint
//This was the step that took me the longest to figure out!
$actionHeader = new SoapHeader('http://www.w3.org/2005/08/addressing','Action','http://tempuri.org/IService/GetData',true);
//Add the headers into the client
$client->__setSoapHeaders($actionHeader);
//Make the call and pass in the variables that we require to go to the server
$retval = $client->__soapCall('GetData',array('value'=>'stuff'));
//Some Error Catching
if (is_soap_fault($retval)) {
    trigger_error("SOAP Fault: (faultcode: {$retval->faultcode}, faultstring: {$retval->faultstring})", E_USER_ERROR);
}

以及工作范围

  <?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="http://tempuri.org/" xmlns:ns2="http://www.w3.org/2005/08/addressing"> 
    <env:Header> 
        <ns2:Action env:mustUnderstand="true">http://tempuri.org/IService/GetData</ns2:Action>
    </env:Header>
    <env:Body>
        <ns1:GetData/>
    </env:Body>
</env:Envelope>

从WCF服务中获取web.config文件

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0"/>
  </system.web>
  <connectionStrings>
    <add name="Timeforce" connectionString="Data Source=apps.ziptrek.com;Initial Catalog=qqest;User ID=qqest; Password=qqest;"
      providerName="System.Data.SqlClient" />
  </connectionStrings>
  <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="TransportSecurity">
          <security mode="Transport">
            <transport clientCredentialType="None"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <services>
      <service name="Service" behaviorConfiguration="Service1">
        <endpoint address="https://localhost/wcftest/Service.svc" binding="wsHttpBinding" bindingConfiguration="TransportSecurity" contract="IService"></endpoint>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="Service1">
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpsGetEnabled="true"/>

          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="httpsService1">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="false"/>


  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
</configuration>

我收到了这个错误:SOAP故障:(故障代码:s:Sender,故障字符串:验证消息安全性时发生错误。) - B. Altan Kocaoglu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接