使用PHP的WCF服务 - 与.NET一起使用,使用PHP反序列化请求时出错

时间:2015-09-16 14:57:50

标签: php vb.net web-services wcf soap-client

我有一个用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中工作。

我很感激这方面的一些帮助!

1 个答案:

答案 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);

现在我收到了结果