我有一个用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中添加了服务引用):
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:发件人]格式化程序抛出了一个 尝试反序列化消息时出现异常:错误 反序列化操作请求消息的主体&#39; GetProduct&#39;。结束 元素&#39;身体&#39;从命名空间 &#39; http://www.w3.org/2003/05/soap-envelope&#39;预期。找到元素 &#39;参数1&#39;来自命名空间&#39;。
我已经在网上看到过几条评论,问题和文章,特别是在SO上。大多数人都建议我没有正确地将我的三个参数传递给服务,但我很确定我是?
我遇到的另一件事是我传递的字符串是&#34; ApiAccess&#34;太长了,但同样的帖子在.NET中工作。
我很感激这方面的一些帮助!
答案 0 :(得分:1)
嗯......我从来没有得到过这方面的答案,但是通过关注@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);
现在我收到了结果