We are attempting to call a function via webservices using PHP. If the Function in NAV has no parameters but is just returning something, it works.
As soon as there is a parameter the Web Services returns this error:
"Parameter passInHelloWorld in method HelloWorld in service TreeNoWebService is null! "
Here is the php code:
if($Client = new NTLMSoapClient($baseUrl))
{
$value = (string)"HelloWorldValue";
$reponse =
@$Client->__call('HelloWorld', array ('passInHelloWorld'=>$value));
die(print_r($response, true));
}
Freddy has a post regarding php but it doesn't inlude a parameter, only a return (
http://blogs.msdn.com/freddyk/archive/2 ... m-php.aspx).
Anyone have any thoughts?
Comments
To call a NAV Webservice you need to pass Credentials (.NET) ... I can't imagine that is possible by PHP, neither by SOAP (correct my if i'm wrong).
A suggestion is to make an ASP.NET proxy that talks to NAV's webservices and then connect to the proxy from your PHP-code by SOAP. Some authentication in the SOAP-header wouldn't hurt (atleast . Thinking of security.
Co-Founder Liberty Grove Software
Author: Programming Microsoft Dynamics NAV (V5.0), 2009, 2013
Our PHP programmer has figured this out. I will post what he did when I can get my hands on it.
jwilder@stonewallkitchen.com
Here is my codeunit:
WebOrderImport(VAR WebOrderImportXMLPort : XMLport "CK Web Order Import") ReturnText : Text[80]
IF WebOrderImportXMLPort.IMPORT THEN BEGIN
ReturnText:='Web Order imported.';
COMMIT;
WebOrdProcessingGCdu.ValidateWebOrders;
WebOrdProcessingGCdu.MakeSalesOrders;
END ELSE
ReturnText:='Web Order Not Imported, Try Again';
Here is the WSDL for the web service it exposes:
- <definitions targetNamespace="urn:microsoft-dynamics-schemas/codeunit/WebOrderImportService" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="urn:microsoft-dynamics-schemas/codeunit/WebOrderImportService">
- <types>
- <schema elementFormDefault="qualified" targetNamespace="urn:microsoft-dynamics-nav/xmlports/WebOrderImport" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="urn:microsoft-dynamics-nav/xmlports/WebOrderImport">
- <complexType name="CustomField">
- <sequence>
<element minOccurs="0" maxOccurs="unbounded" name="CustomFieldName" type="string" />
<element minOccurs="0" maxOccurs="unbounded" name="CustomFieldValue" type="string" />
</sequence>
</complexType>
- <complexType name="CustomFields" mixed="true">
- <sequence>
<element minOccurs="0" maxOccurs="unbounded" name="CustomField" type="tns:CustomField" />
</sequence>
</complexType>
- <complexType name="Item">
- <sequence>
<element minOccurs="0" maxOccurs="1" name="ItemCode" type="string" />
<element minOccurs="0" maxOccurs="1" name="Variant" type="string" />
<element minOccurs="0" maxOccurs="unbounded" name="Description" type="string" />
<element minOccurs="0" maxOccurs="unbounded" name="Logo" type="string" />
<element minOccurs="0" maxOccurs="1" name="Quantity" type="string" />
<element minOccurs="0" maxOccurs="1" name="Price" type="string" />
<element minOccurs="0" maxOccurs="unbounded" name="CustomFields" type="tns:CustomFields" />
</sequence>
</complexType>
- <complexType name="Items" mixed="true">
- <sequence>
<element minOccurs="1" maxOccurs="unbounded" name="Item" type="tns:Item" />
</sequence>
</complexType>
- <complexType name="order">
- <sequence>
<element minOccurs="1" maxOccurs="1" name="CustomerCode" type="string" />
<element minOccurs="1" maxOccurs="1" name="ShipToContact" type="string" />
<element minOccurs="1" maxOccurs="1" name="ShipToAddress" type="string" />
<element minOccurs="1" maxOccurs="1" name="ShipToAddress2" type="string" />
<element minOccurs="1" maxOccurs="1" name="ShipToCity" type="string" />
<element minOccurs="1" maxOccurs="1" name="ShipToState" type="string" />
<element minOccurs="1" maxOccurs="1" name="ShipToZIP" type="string" />
<element minOccurs="0" maxOccurs="1" name="ShipToCountry" type="string" />
<element minOccurs="1" maxOccurs="1" name="SalesRepCode" type="string" />
<element minOccurs="1" maxOccurs="1" name="ShipViaCode" type="string" />
<element minOccurs="1" maxOccurs="1" name="DeliveryDate" type="string" />
<element minOccurs="1" maxOccurs="1" name="CustomerPONo" type="string" />
<element minOccurs="1" maxOccurs="1" name="SeparateShipment" type="string" />
<element minOccurs="1" maxOccurs="unbounded" name="Items" type="tns:Items" />
</sequence>
</complexType>
<element name="order" type="tns:order" />
</schema>
- <schema elementFormDefault="qualified" targetNamespace="urn:microsoft-dynamics-schemas/codeunit/WebOrderImportService" xmlns="http://www.w3.org/2001/XMLSchema">
- <element name="WebOrderImport">
- <complexType>
- <sequence>
<element minOccurs="1" maxOccurs="1" name="webOrderImportXMLPort" type="q1:order" xmlns:q1="urn:microsoft-dynamics-nav/xmlports/WebOrderImport" />
</sequence>
</complexType>
</element>
- <element name="WebOrderImport_Result">
- <complexType>
- <sequence>
<element minOccurs="1" maxOccurs="1" name="return_value" type="string" />
<element minOccurs="1" maxOccurs="1" name="webOrderImportXMLPort" type="q2:order" xmlns:q2="urn:microsoft-dynamics-nav/xmlports/WebOrderImport" />
</sequence>
</complexType>
</element>
</schema>
</types>
- <message name="WebOrderImport">
<part name="parameters" element="tns:WebOrderImport" />
</message>
- <message name="WebOrderImport_Result">
<part name="parameters" element="tns:WebOrderImport_Result" />
</message>
- <portType name="WebOrderImportService_Port">
- <operation name="WebOrderImport">
<input name="WebOrderImport" message="tns:WebOrderImport" />
<output name="WebOrderImport_Result" message="tns:WebOrderImport_Result" />
</operation>
</portType>
- <binding name="WebOrderImportService_Binding" type="tns:WebOrderImportService_Port">
<binding transport="http://schemas.xmlsoap.org/soap/http" xmlns="http://schemas.xmlsoap.org/wsdl/soap/" />
- <operation name="WebOrderImport">
<operation soapAction="urn:microsoft-dynamics-schemas/codeunit/WebOrderImportService:WebOrderImport" style="document" xmlns="http://schemas.xmlsoap.org/wsdl/soap/" />
- <input name="WebOrderImport">
<body use="literal" xmlns="http://schemas.xmlsoap.org/wsdl/soap/" />
</input>
- <output name="WebOrderImport_Result">
<body use="literal" xmlns="http://schemas.xmlsoap.org/wsdl/soap/" />
</output>
</operation>
</binding>
- <service name="WebOrderImportService">
- <port name="WebOrderImportService_Port" binding="tns:WebOrderImportService_Binding">
<address location="http://ck-test-1.ck1.dmn:7047/DynamicsNAV/WS/ReplaceWithAPercentEncodedCompanyName/Codeunit/WebOrderImportService" xmlns="http://schemas.xmlsoap.org/wsdl/soap/" />
</port>
</service>
</definitions>
Here is the SOAP I send
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:microsoft-dynamic\
s-nav/xmlports/WebOrderImport" xmlns:ns2="urn:microsoft-dynamics-schemas/codeunit/WebOrderImportService"><SOAP-ENV:Body><ns2:WebOrderImport><ns2:webOrderImportXMLPort><ns1:order><ns1:CustomerCode>1111</ns1:CustomerCode><ns1:ShipToContact>Chris Grill</ns1:ShipToContact><ns1:ShipToAddress>153 Rosewood Ave</ns1:Sh\
ipToAddress><ns1:ShipToAddress2></ns1:ShipToAddress2><ns1:ShipToCity>Wherever</ns1:ShipToCity><ns1:ShipToState>PA</ns1:ShipToState><ns1:ShipToZIP>55555</n\
s1:ShipToZIP><ns1:ShipToCountry>United States</ns1:ShipToCountry><ns1:SalesRepCode>WEB</ns1:SalesRepCode><ns1:ShipViaCode>UPS Ground</ns1:ShipViaCode><ns1:D\
eliveryDate>1969-12-31</ns1:DeliveryDate><ns1:CustomerPONo>TT3859</ns1:CustomerPONo><ns1:SeparateShipment>0</ns1:SeparateShipment><ns1:Items><ns1:Item><ns1\
:ItemCode>4300</ns1:ItemCode><ns1:Variant>PB-KHA</ns1:Variant><ns1:Description>Visor</ns1:Description><ns1:Quantity>1</ns1:Quantity><ns1:Price>5.0000</ns1:P\
rice></ns1:Item></ns1:Items></ns1:order></ns2:webOrderImportXMLPort></ns2:WebOrderImport></SOAP-ENV:Body></SOAP-ENV:Envelope>'
SOAP returned
<Soap:Envelope xmlns:Soap="http://schemas.xmlsoap.org/soap/envelope/"><Soap:Body><WebOrderImport_Re\
sult xmlns="urn:microsoft-dynamics-schemas/codeunit/WebOrderImportService"><return_value>Web Order Not Imported, Try Again</return_value><webOrderImportXMLPort><CustomerCode xmlns="ur\
n:microsoft-dynamics-nav/xmlports/WebOrderImport"/><ShipToContact xmlns="urn:microsoft-dynamics-nav/xmlports/WebOrderImport"/><ShipToAddress xmlns="urn:micr\
osoft-dynamics-nav/xmlports/WebOrderImport"/><ShipToAddress2 xmlns="urn:microsoft-dynamics-nav/xmlports/WebOrderImport"/><ShipToCity xmlns="urn:microsoft-dy\
namics-nav/xmlports/WebOrderImport"/><ShipToState xmlns="urn:microsoft-dynamics-nav/xmlports/WebOrderImport"/><ShipToZIP xmlns="urn:microsoft-dynamics-nav/x\
mlports/WebOrderImport"/><ShipToCountry xmlns="urn:microsoft-dynamics-nav/xmlports/WebOrderImport"/><SalesRepCode xmlns="urn:microsoft-dynamics-nav/xmlports\
/WebOrderImport"/><ShipViaCode xmlns="urn:microsoft-dynamics-nav/xmlports/WebOrderImport"/><DeliveryDate xmlns="urn:microsoft-dynamics-nav/xmlports/WebOrder\
Import"/><CustomerPONo xmlns="urn:microsoft-dynamics-nav/xmlports/WebOrderImport"/><SeparateShipment xmlns="urn:microsoft-dynamics-nav/xmlports/WebOrderImpo\
rt"/><Items xmlns="urn:microsoft-dynamics-nav/xmlports/WebOrderImport"><Item><ItemCode/><Variant/><Description/><Logo/><Quantity>0</Quantity><Price>0.00</Pr\
ice><CustomFields/></Item></Items></webOrderImportXMLPort></WebOrderImport_Result></Soap:Body></Soap:Envelope>
If so, you can't do that. What you could do is call a Codeunit function, pass in the location (e.g. a path string) of the XML data, then invoke the XMLport from the Codeunit function to go read the data from the passed path. There are other approaches that would also work. But we haven't thought of any way that you could utiilize the XMLPort directly as a function parameter. If we didn't interpret your code correctly, let us know.
Co-Founder Liberty Grove Software
Author: Programming Microsoft Dynamics NAV (V5.0), 2009, 2013
Assuming you are using the NTLMSoapClient and NTLMStream classes unaltered, and you have set the useNTLM property set to 'TRUE' in the config file in the NAV folder, then this code should work. It works for me. This example passes a lowercase string to a NAV Codeunit Webservice which returns the string in uppercase. Here's the PHP:
define('USERPWD', 'localhost\Username:Password');
$baseURL = 'http://localhost:7047/DynamicsNAV/WS/';
$companyName = "CRONUS Nederland NV";
stream_wrapper_unregister('http');
stream_wrapper_register('http', 'App_NTLMStream') or die("Failed to register protocol");
$pageURL = $baseURL.rawurlencode($companyName).'/Codeunit/Letters'; // 'Letters' is the name of the Codeunit..
$client = new App_NTLMSoapClient($pageURL);
$params = array('inputstring' => 'test');
$result = $client->Capitalize($params);
$string = $result->return_value;
stream_wrapper_restore('http');
echo $string;
die();
// output: "TEST"
In my actual implementation I do have three classes to abstract the nitty-gritty away. An abstract class which is extended by either a page class to have a 1 size fits all solution for all Pages or a dedicated class which deals with the codeunits. In practice, to delete something it will look like this in case of a Page:
$namespace = $this->_request->getParam('namespace'); // get the type from somewhere, like Customer, Order etc.
$no = $this->_request->getParam('No'); // fetch the key (or composed key) from somewhere
$pageModel = new App_Page($namespace); // instantiate the model
$pageModel->deleteItem($no); // call a method
Happy coding..
I tried your code and I get this error, maybe you can help me even if 5 years are gone..
Fatal error: Uncaught SoapFault exception: [Client] Function ("capitalize") is not a valid method for this service in C:\wamp\www\nav\letters.php:15 Stack trace: #0 C:\wamp\www\nav\letters.php(15): SoapClient->__call('capitalize', Array) #1 C:\wamp\www\nav\letters.php(15): NTLMSoapClient->capitalize(Array) #2 {main} thrown in C:\wamp\www\nav\letters.php on line 15
Thanks in advance.
Federico
MBS Specialist since NAV 2.0
My experiences on Linkedin
<?php
define('USERPWD', 'domain\\user:pwd');
require('soapclass.php');
require('streamclass.php');
$baseURL = 'http://EXP120.local:7047/DynamicsNAV90/WS/';
$companyName = "CRONUS Italia S.p.A.";
stream_wrapper_unregister('http');
stream_wrapper_register('http', 'NTLMStream') or die("Failed to register protocol");
$pageURL = 'http://EXP120.local:7047/DynamicsNAV90/WS/CRONUS Italia S.p.A./Codeunit/letters'; // 'Letters' is the name of the Codeunit..
$client = new NTLMSoapClient($pageURL);
$params = array();
$params["param1"] = 'test';
$result = $client->capitalize($params);
$string = $result->return_value;
stream_wrapper_restore('http');
echo $string;
die();
?>
Federico
MBS Specialist since NAV 2.0
My experiences on Linkedin
Federico
MBS Specialist since NAV 2.0
My experiences on Linkedin