2015-06-19 148 views
2

幾天來,我一直在努力獲得PHP webshop和帶有NTLM認證的navision服務器之間的連接。現在連接和身份驗證已完成,我在處理正確的請求時遇到問題。對navision webservice的PHP SOAP請求

對於本例,我嘗試使用函數(ItemPriceDiscInventory)來檢索價格信息。

的URL我從客戶擁有的是:http://IP:PORT/MSIteminfoTest/WS/Saniceve%20BV/Codeunit/ItemPriceDiscInventory

我曾嘗試2種方法發出請求:

捲曲後與原始的XML

的原始XML由給定顧客。輸入(本地)WSDL文件時,這與測試程序(SOACleaner)提供的XML相同。

$request = ' 
<InputItemPriceDiscInventory_PortGetPriceDiscInvInformation xmlns="http://xyrow.com"> 
<Body xmlns=""> 
<GetPriceDiscInvInformation xmlns="urn:microsoft-dynamics-schemas/codeunit/ItemPriceDiscInventory"> 
    <itemPriceDiscInventory> 
    <Item xmlns="urn:microsoft-dynamics-nav/xmlports/x50005"> 
     <Klantnummer /> 
     <Artikelnr /> 
     <Aantal /> 
     <KortingsPercentage1 /> 
     <KortingsPercentage2 /> 
     <NettoPerEenheid /> 
     <BeschikbareVoorraad /> 
     <WebShopVoorraad /> 
    </Item> 
    </itemPriceDiscInventory> 
    <customerNo>1234</customerNo> 
    <itemNo>5678</itemNo> 
    <quantityVarDec>1</quantityVarDec> 
</GetPriceDiscInvInformation> 
</Body> 
</InputItemPriceDiscInventory_PortGetPriceDiscInvInformation>'; 

我的要求:

$ch = curl_init(); 
$headers = array( 
     'Method: POST', 
     'Connection: Keep-Alive',  
     'Content-Type: text/xml; charset=utf-8',    
     "Host: {$ip}:{$port}", 
     "Accept: */*"      
    );  
curl_setopt($ch, CURLOPT_URL,   $url);   
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
curl_setopt($ch, CURLOPT_POST,   true);   
curl_setopt($ch, CURLOPT_POSTFIELDS, $request); 
curl_setopt($ch, CURLOPT_USERPWD, 'usr:pass'); 
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_NTLM); 
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);   
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);  
curl_setopt($ch, CURLOPT_FAILONERROR, 0); 

這將返回WSDL文件,不管我包括哪些POST值。如果我包括頭'SOAPAction: "ItemPriceDiscInventory"'它給我的錯誤:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><s:Fault><faultcode xmlns:a="urn:microsoft-dynamics-schemas/error">a:System.Net.WebException</faultcode><faultstring xml:lang="nl-NL">Soap message is invalid!</faultstring><detail><string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">Soap message is invalid!</string></detail></s:Fault></s:Body></s:Envelope> 

的WSDL看起來像:

<definitions targetNamespace="urn:microsoft-dynamics-schemas/codeunit/ItemPriceDiscInventory" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="urn:microsoft-dynamics-schemas/codeunit/ItemPriceDiscInventory"> 
<types> 
    <schema elementFormDefault="qualified" targetNamespace="urn:microsoft-dynamics-nav/xmlports/x50005" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="urn:microsoft-dynamics-nav/xmlports/x50005"> 
     <complexType name="Item"> 
      <sequence> 
       <element minOccurs="1" maxOccurs="1" name="Klantnummer" type="string"/> 
       <element minOccurs="1" maxOccurs="1" name="Artikelnr" type="string"/> 
       <element minOccurs="1" maxOccurs="1" name="Aantal" type="string"/> 
       <element minOccurs="1" maxOccurs="1" name="KortingsPercentage1" type="string"/> 
       <element minOccurs="1" maxOccurs="1" name="KortingsPercentage2" type="string"/> 
       <element minOccurs="1" maxOccurs="1" name="NettoPerEenheid" type="string"/> 
       <element minOccurs="1" maxOccurs="1" name="BeschikbareVoorraad" type="string"/> 
       <element minOccurs="1" maxOccurs="1" name="WebShopVoorraad" type="string"/> 
      </sequence> 
     </complexType> 
     <complexType name="ItemPriceDiscInvInfo" mixed="true"> 
      <sequence> 
       <element minOccurs="1" maxOccurs="1" name="Item" type="tns:Item"/> 
      </sequence> 
     </complexType> 
     <element name="ItemPriceDiscInvInfo" type="tns:ItemPriceDiscInvInfo"/> 
    </schema> 
    <schema elementFormDefault="qualified" targetNamespace="urn:microsoft-dynamics-schemas/codeunit/ItemPriceDiscInventory" xmlns="http://www.w3.org/2001/XMLSchema"> 
     <element name="GetPriceDiscInvInformation"> 
      <complexType> 
       <sequence> 
        <element minOccurs="1" maxOccurs="1" name="itemPriceDiscInventory" type="q1:ItemPriceDiscInvInfo" xmlns:q1="urn:microsoft-dynamics-nav/xmlports/x50005"/> 
        <element minOccurs="1" maxOccurs="1" name="customerNo" type="string"/> 
        <element minOccurs="1" maxOccurs="1" name="itemNo" type="string"/> 
        <element minOccurs="1" maxOccurs="1" name="quantityVarDec" type="decimal"/> 
       </sequence> 
      </complexType> 
     </element> 
     <element name="GetPriceDiscInvInformation_Result"> 
      <complexType> 
       <sequence> 
        <element minOccurs="1" maxOccurs="1" name="itemPriceDiscInventory" type="q2:ItemPriceDiscInvInfo" xmlns:q2="urn:microsoft-dynamics-nav/xmlports/x50005"/> 
       </sequence> 
      </complexType> 
     </element> 
    </schema> 
</types> 
<message name="GetPriceDiscInvInformation"> 
    <part name="parameters" element="tns:GetPriceDiscInvInformation"/> 
</message> 
<message name="GetPriceDiscInvInformation_Result"> 
    <part name="parameters" element="tns:GetPriceDiscInvInformation_Result"/> 
</message> 
<portType name="ItemPriceDiscInventory_Port"> 
    <operation name="GetPriceDiscInvInformation"> 
     <input name="GetPriceDiscInvInformation" message="tns:GetPriceDiscInvInformation"/> 
     <output name="GetPriceDiscInvInformation_Result" message="tns:GetPriceDiscInvInformation_Result"/> 
    </operation> 
</portType> 
<binding name="ItemPriceDiscInventory_Binding" type="tns:ItemPriceDiscInventory_Port"> 
    <binding transport="http://schemas.xmlsoap.org/soap/http" xmlns="http://schemas.xmlsoap.org/wsdl/soap/"/> 
    <operation name="GetPriceDiscInvInformation"> 
     <operation soapAction="urn:microsoft-dynamics-schemas/codeunit/ItemPriceDiscInventory:GetPriceDiscInvInformation" style="document" xmlns="http://schemas.xmlsoap.org/wsdl/soap/"/> 
     <input name="GetPriceDiscInvInformation"> 
      <body use="literal" xmlns="http://schemas.xmlsoap.org/wsdl/soap/"/> 
     </input> 
     <output name="GetPriceDiscInvInformation_Result"> 
      <body use="literal" xmlns="http://schemas.xmlsoap.org/wsdl/soap/"/> 
     </output> 
    </operation> 
</binding> 
<service name="ItemPriceDiscInventory"> 
    <port name="ItemPriceDiscInventory_Port" binding="tns:ItemPriceDiscInventory_Binding"> 
     <address location="http://IP:PORT/MSIteminfoTest/WS/Saniceve%20BV/Codeunit/ItemPriceDiscInventory" xmlns="http://schemas.xmlsoap.org/wsdl/soap/"/> 
    </port> 
</service> 
</definitions> 

PHP SoapClient的要求

好吧,我想嘗試的SOAP功能PHP。我使用NTLMSoapClient類進行身份驗證,這似乎是正確的。 如果我構建WSDL模式的客戶端,與上面給出的網址,它不能解析WSDL:

[WSDL] SOAP-ERROR: Parsing WSDL: Couldn't load from 'URL' : Start tag expected, '<' 

但如果我這樣做在非WSDL模式,並在參數給出的位置,我「M具有一些結果...

stream_wrapper_unregister('http'); 
stream_wrapper_register('http', 'MyServiceProviderNTLMStream') or die("Failed to register protocol"); 

$client = new MyServiceNTLMSoapClient(null,array( 'location' => $url, 
                'uri'  => "http://schemas.xmlsoap.org/wsdl/soap/", 
                'trace' => 1)); 

$itemPriceDiscInventory = array(
       "Item" => array(
        "Klantnummer" => null, 
        "Artikelnr" => null, 
        "Aantal" => null, 
        "KortingsPercentage" => null, 
        "NettoPerEenheid" => null, 
        "Voorraad" => null 
       ) 
      ); 

$params = array(
      "itemPriceDiscInventory" => $itemPriceDiscInventory, 
      "customerNo" => '0000265', 
      "itemNo" => 'SAN483539', 
      "quantityVarDec" => '1.0' 
); 


echo $client->GetPriceDiscInvInformation($params); 

stream_wrapper_restore('http'); 

這將導致一個錯誤。如果我有最後一個請求和響應它給了我:

<?xml version="1.0" encoding="UTF-8"?> 
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="http://xml.apache.org/xml-soap" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> 
<SOAP-ENV:Body> 
    <ns1:GetPriceDiscInvInformation> 
     <param0 xsi:type="ns2:Map"> 
      <item> 
       <key xsi:type="xsd:string">itemPriceDiscInventory</key> 
       <value xsi:type="ns2:Map"> 
        <item> 
         <key xsi:type="xsd:string">Item</key> 
         <value xsi:type="ns2:Map"> 
          <item> 
           <key xsi:type="xsd:string">Klantnummer</key> 
           <value xsi:nil="true"/> 
          </item> 
          <item> 
           <key xsi:type="xsd:string">Artikelnr</key> 
           <value xsi:nil="true"/> 
          </item> 
          <item> 
           <key xsi:type="xsd:string">Aantal</key> 
           <value xsi:nil="true"/> 
          </item> 
          <item> 
           <key xsi:type="xsd:string">KortingsPercentage</key> 
           <value xsi:nil="true"/> 
          </item> 
          <item> 
           <key xsi:type="xsd:string">NettoPerEenheid</key> 
           <value xsi:nil="true"/> 
          </item> 
          <item> 
           <key xsi:type="xsd:string">Voorraad</key> 
           <value xsi:nil="true"/> 
          </item> 
         </value> 
        </item> 
       </value> 
      </item> 
      <item> 
       <key xsi:type="xsd:string">customerNo</key> 
       <value xsi:type="xsd:string">0000265</value> 
      </item> 
      <item> 
       <key xsi:type="xsd:string">itemNo</key> 
       <value xsi:type="xsd:string">SAN483539</value> 
      </item> 
      <item> 
       <key xsi:type="xsd:string">quantityVarDec</key> 
       <value xsi:type="xsd:string">1.0</value> 
      </item> 
     </param0> 
    </ns1:GetPriceDiscInvInformation> 
</SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 

響應:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> 
<s:Body> 
    <s:Fault> 
     <faultcode xmlns:a="urn:microsoft-dynamics-schemas/error">a:Microsoft.Dynamics.Nav.Service.WebServices.ServiceBrokerException</faultcode> 
     <faultstring xml:lang="nl-NL">Parameter itemPriceDiscInventory in method GetPriceDiscInvInformation in service ItemPriceDiscInventory is null!</faultstring> 
     <detail> 
      <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">Parameter itemPriceDiscInventory in method GetPriceDiscInvInformation in service ItemPriceDiscInventory is null!</string> 
     </detail> 
    </s:Fault> 
</s:Body> 

所以,看來他正試圖解析它,但請求不正確的格式。注意:我不確切知道uri參數是什麼。這是我可以從WSDL讀取的東西嗎?

如果我看看客戶給我的請求和SOAP請求,它有很大的不同(第一個看起來不像SOAP),但是對於SOAP請求,它似乎是我得到的接近一點。

對此有何看法?

+0

我們有承包商通過php調用我們的客戶Navision web服務,但我測試了VisualStudio.NET中的操作實際工作(快速版是免費和優秀的)。從那裏我可以使用[Fiddler](http://www.telerik.com/fiddler)等應用程序來跟蹤請求/響應。有了這些信息,你可以檢查你的頭文件是否正確,並且XML請求格式正確... VS很少使用Web服務並開始測試。 –

+0

您是否考慮過使用OData作爲SOAP的替代品? IMO,OData標準更易於理解,另外一個優點是您可以使用Json而不是XML來進行客戶端和服務器之間的通信。 –

回答

1

我終於明白了。首先,我認爲我的請求中的命名空間有問題。

我將WSDL文件保存在我們自己的服務器上,並將其用於WSDL模式下的soapclient,並將navision服務器用作位置。這工作!

我不知道爲什麼我不能在WSDL模式下使用直接URL,但這是一個可接受的解決方法。