我在使用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。编辑#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>
任何建议??
谢谢! 安迪
答案 0 :(得分:6)
好的,我让这个工作了。感谢戈尔让我仔细检查了我之前忽略过的东西。
我结束了放弃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>