我有一个用VB.net编写的WCF服务。
当我在Visual Studio中向项目添加服务引用并通过VB或C#与之通信时,一切正常。
但是,用PHP时,我整个下午都在浪费,无法得到答复。
我的PHP代码是:
error_reporting(E_ALL & ~E_NOTICE); // Enable errors
ini_set('display_errors', 'On');
// Declare parameters for soapclient. Need to make sure its set to soap 1.2
$params = array("soap_version"=> SOAP_1_2,
"trace"=>1,
"exceptions"=>1
);
// Create the soap client
$client = new SoapClient($url,$params);
// add some WSAddressing Headers in. Ensure that you have the Namespace as the address if you are using wsHttpBinding on the endpoint
$actionHeader = new SoapHeader('http://www.w3.org/2005/08/addressing','Action','http://tempuri.org/ISamProductQ/GetProduct',true);
// "To" header which took ages to figure out and generated errors when missing
$toHeader = new SoapHeader('http://www.w3.org/2005/08/addressing','To','https://sam.thinkka.com/Api/SamProductQ.svc', true);
$headers = array();
array_push($headers, $actionHeader) ;
array_push($headers, $toHeader) ;
// Add the headers
$client->__setSoapHeaders($headers);
// Posted variables
$url = 'https://sam.thinkka.com/api/SamProductQ.svc/Api/SamProductQ.svc/mex?wsdl';
$sku= 'PRODUCT_SKU';
$ApiAccess='A VERY LONG ENCODED STRING' ;
$Site='www.websiteaddress.co.uk';
//Make the call and pass in the variables that we require to go to the server
$retval = $client->__soapCall("GetProduct", array($sku, $ApiAccess, $Site));
等效的.NET客户端代码(已在VS中添加了Service Reference):
Dim s As New SamProductFeed.SamProductQClient
Dim Result as Sam_Product = s.GetProduct(SKU:="PRODUCT_SKU", ApiAccess:="A long encoded string", QueryingWebsite:="www.websiteaddress.co.uk")
服务服务器上GetProduct
函数的第一行看起来像:
<AspNetCompatibilityRequirements(RequirementsMode:=AspNetCompatibilityRequirementsMode.Allowed)> _
<KnownType(GetType(Sam_Product))> _
Public Class SamProductQ
Implements ISamProductQ
Public Function GetProduct(ByVal SKU As String, ApiAccess As String, QueryingWebsite As String) As Sam_Product Implements ISamProductQ.GetProduct
..... Do Stuff and return "Sam_Product" complex object
End Function
我已经像这样设置了Web.config服务:
<services>
<service behaviorConfiguration="SamProductQ.Behavior" name="SAM.SamProductQ">
<host>
<baseAddresses>
<add baseAddress="https://sam.thinkka.com/Api/SamProductQ.svc"/>
</baseAddresses>
</host>
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="SamProductQBinding" contract="SAM.ISamProductQ">
</endpoint>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange">
</endpoint>
</service>
</services>
具有其他配置属性:
<behavior name="SamProductQ.Behavior">
<serviceMetadata httpsGetEnabled="true" httpGetEnabled="true" httpsGetUrl="/Api/SamProductQ.svc/mex"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
<binding name="SamProductQBinding">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
当我运行上面的PHP代码时,出现以下错误:
未捕获的SoapFault异常:[s:Sender]格式化程序抛出了一个尝试反序列化消息时发生异常:将操作“ GetProduct”的请求消息反序列化。结束命名空间中的元素“正文”预期为“ http://www.w3.org/2003/05/soap-envelope”。找到的元素来自名称空间“'的'param1'。
我已经在网上,尤其是在SO上看到了一些评论,问题和文章。大多数建议我没有将我的三个参数正确地传递给服务,但是我很确定自己是吗?
发生的另一件事是我作为“ ApiAccess”传递的字符串是否太长,但是同一帖子在.NET中有效。
我希望在此方面有所帮助!
嗯...我从来没有得到答案,但是通过遵循@Tom Redfern的技巧,我可以通过将绑定更改为basicHttpBinding,然后更改我的PHP代码来使其工作。
<basicHttpBinding>
<binding name="SamProductQBinding" maxReceivedMessageSize="2147483647">
<security mode="Transport" />
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
</binding>
</basicHttpBinding>
<services>
<service behaviorConfiguration="SamProductQ.Behavior" name="SAM.SamProductQ">
<host>
<baseAddresses>
<add baseAddress="https://sam.thinkka.com/Api/SamProductQ.svc"/>
</baseAddresses>
</host>
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="SamProductQBinding" contract="SAM.ISamProductQ"></endpoint>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"></endpoint>
</service>
</services>
以及我的PHP代码:
$url = 'https://sam.thinkka.com/api/SamProductQ.svc/Api/SamProductQ.svc/mex?wsdl';
$params = array("soap_version"=> SOAP_1_1,
"trace"=>1,
"exceptions"=>1
);
$client = new SoapClient($url, $params);
// Parameters for the API
$ApiAccess='a long encoded string' ;
$Site='www.websiteaddress.co.uk';
$sku= 'RP1-16C'; // for single product
// Make the call and pass in the variables that we require to go to the server
// SINGLE PRODUCT:
$GetProductResult = LowerCaseArray($client->__soapCall("GetProduct", array(array(SKU=>$sku, ApiAccess=>$ApiAccess, QueryingWebsite=>$Site)))->GetProductResult);
现在我正在获得结果
[Sajida Ali hous 167/4 gali no 3 punjabi biste gulsn chok baljeet nagar New Delhi pin no 110008 m.n.7084308930 whirlpool R.f.没有科林·坎普兰[]