通过身份验证从PHP使用.NET SOAP服务

时间:2011-10-31 21:10:20

标签: php .net soap soap-client

我一直在寻找解决方案几天,但没有运气。

我从http://www.codingfriends.com/index.php/2010/04/16/soap-client-calling-net-web-service/获得了初学者代码。

这是调整后的代码(使用假密钥):

<?php
// create a connection to the local host mono .NET pull back the wsdl to get the functions names
// and also the parameters and return values
$client = new SoapClient("https://realServer/events.asmx?WSDL",
array(
  "trace"      => 1,        // enable trace to view what is happening
  "exceptions" => 0,        // disable exceptions
  "cache_wsdl" => 0)        // disable any caching on the wsdl, encase you alter the wsdl server
);

// get a response from the WSDL zend server function getQuote for the day monday
print_r( $client->GetSingleEvent(array("APIKey" => "HISY20Y4-8405-91SK-L0S7-9A17252E548A", "EventId" => "2559")));

// display what was sent to the server (the request)
echo "<p>Request :".htmlspecialchars($client->__getLastRequest()) ."</p>";
// display the response from the server
echo "<p>Response:".htmlspecialchars($client->__getLastResponse())."</p>";
?>

这是实际的xml请求应该是什么样的(在Soap UI中测试)

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/" xmlns:cer="http://cermsystem.net/">
<soapenv:Header>
  <tem:Credentials>
     <!--Optional:-->

  <tem:APIKey>HISY20Y4-8405-91SK-L0S7-9A17252E548A</tem:APIKey></tem:Credentials>
</soapenv:Header>
<soapenv:Body>
  <tem:GetSingleEvent>
     <!--Optional:-->
     <cer:GetEventByIDRQ>
        <!--Optional:-->

     <cer:EventId>2559</cer:EventId></cer:GetEventByIDRQ>
  </tem:GetSingleEvent>
</soapenv:Body>
</soapenv:Envelope>

这是我在发送到.NET SOAP服务器后从脚本获得的当前输出:

SoapFault Object ( [message:protected] => Server was unable to process request. ---> Object reference not set to an instance of an object. 
[string:Exception:private] => [code:protected] => 0 [file:protected] => /Library/WebServer/Documents/soap6.php [line:protected] => 15 [trace:Exception:private] => Array ( [0] => Array ( [file] => /Library/WebServer/Documents/soap6.php [line] => 15 [function] => __call [class] => SoapClient [type] => -> [args] => Array ( [0] => GetSingleEvent [1] => Array ( [0] => Array ( [APIKey] => 8F0A395B-8405-480B-871C-9A17252E548A ) ) ) ) [1] => Array ( [file] => /Library/WebServer/Documents/soap6.php [line] => 15 [function] => GetSingleEvent [class] => SoapClient [type] => -> [args] => Array ( [0] => Array ( [APIKey] => 8F0A395B-8405-480B-871C-9A17252E548A ) ) ) ) [previous:Exception:private] => [faultstring] => Server was unable to process request. ---> Object reference not set to an instance of an object. [faultcode] => soap:Server [detail] => )

Request :<?xml version="1.0" encoding="UTF-8"?> 
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://tempuri.org/">
<SOAP-ENV:Body>
<ns1:GetSingleEvent/>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Response:<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>Server was unable to process request. ---&gt; Object reference not set to an instance of an object.</faultstring>
<detail />
</soap:Fault>
</soap:Body>
</soap:Envelope>

我认为问题是.NET服务器没有收到APIKey和EventId的正确输入,但我一直无法使该部分工作。 APIKey是否需要作为标题的一部分发送?如果是这样,我将如何与阅读WSDL

结合使用

1 个答案:

答案 0 :(得分:1)

在您的模型中,正确的XML,您有'APIKey',并且嵌套在SOAP标头内的'Credentials'元素中。您的PHP代码不会生成此代码。

您需要this function这样的内容,允许您向soap请求添加标头。您要添加的标题是这样的:

$ns = 'http://tempuri.org/'; //Namespace of the webservice
$headerbody = array("APIKey" => "HISY20Y4-8405-91SK-L0S7-9A17252E548A");

//Create Soap Header.        
$header = new SOAPHeader($ns, 'Credentials', $headerbody);        

//set the Headers of Soap Client. 
$client->__setSoapHeaders($header); 

此时,您的请求应该有效(尽管该代码未经测试)。