Search code examples
phpmicrosoft-dynamicsnavisionmicrosoft-dynamics-navdynamics-nav-2016

Dynamics NAV 2016 Web Service: Parameter * in method * in service * is null


I try to get a single contact from my Dynamics Nav Web Service (Dynamics Nav 2016). I do this with a SOAP-request in PHP.

The web service is a codeunit which contains two functions:

fGetContact(iContactNumber : Text[20]) oContact : Text[250]
IF rContact.GET(iContactNumber) THEN BEGIN
  oContact := '';
  oContact := rContact."No." + ';' +
              rContact."Company Name" + ';' +
              rContact."First Name" + ';' +
              rContact.Surname + ';' +
              rContact."E-Mail";
END;
EXIT(oContact);

fGetContacts() oContacts : Text[250]
IF rContact.GET('KT100190') THEN BEGIN
  oContacts := '';
  oContacts := rContact."No." + ';' +
               rContact."Company Name" + ';' +
               rContact."First Name" + ';' +
               rContact.Surname + ';' +
               rContact."E-Mail";
END;
EXIT(oContacts);

The second function, fGetContacts, works fine. But when I call fGetContact with a contact number as parameter, it returns the following error:

Parameter iContactNumber in method FGetContact in service MyService is null!

I use the NTLMSoapClient like the following:

<?php
ini_set('soap.wsdl_cache_enabled', '0'); 

require_once 'ntlmstream.php';
require_once 'ntlmsoapclient.php';

$url = 'http://localhost:7047/DynamicsNAV90/WS/CRONUS/Codeunit/MyService';

$options = array(
    'uri' => $url,
    'location' => $url,
    'trace' => true,
    'login' => 'my_user',
    'password' => 'my_password'
);

// we unregister the current HTTP wrapper
stream_wrapper_unregister('http');

// we register the new HTTP wrapper
stream_wrapper_register('http', 'MyServiceProviderNTLMStream') or die("Failed to register protocol");

// so now all request to a http page will be done by MyServiceProviderNTLMStream.
// ok now, let's request the wsdl file
// if everything works fine, you should see the content of the wsdl file
$client = new MyServiceNTLMSoapClient(null, $options);

// should display your reply
try {
    $params = array('iContactNumber' => 'KT100190');

    echo '<pre>';
    echo $client->FGetContacts(); // works
    echo $client->FGetContact($params); // doesn't work
    echo '</pre>';
} catch (SoapFault $e) {
    echo '<pre>';
    var_dump($e);
    echo '</pre>';
}

// restore the original http protocole
stream_wrapper_restore('http');

I also tried to call the function like this:

echo $client->FGetContact('KT100190');

The return error is the same as before.

I tested my function with SoapUI and the return value is exactly what it shuold be.

Request:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:new="urn:microsoft-dynamics-schemas/codeunit/MyService">
   <soapenv:Header/>
   <soapenv:Body>
      <new:FGetContact>
         <new:iContactNumber>KT100190</new:iContactNumber>
      </new:FGetContact>
   </soapenv:Body>
</soapenv:Envelope>

Response:

<Soap:Envelope xmlns:Soap="http://schemas.xmlsoap.org/soap/envelope/">
   <Soap:Body>
      <FGetContact_Result xmlns="urn:microsoft-dynamics-schemas/codeunit/MyService">
         <return_value>KT100190;Add-ON Marketing;Chris;McGurk;[email protected]</return_value>
      </FGetContact_Result>
   </Soap:Body>
</Soap:Envelope>

So what am I doing wrong that this error appears and how can I fix it?


Solution

  • I made a workaround and it works for me now.

    I changed the $request variable in the class NTLMSoapClient, because the soap envelope that php sent to my service was absolutely useless.

    So basically I just did this before the curl actions:

    $request = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:new="urn:microsoft-dynamics-schemas/codeunit/MyService">
                   <soapenv:Header/>
                   <soapenv:Body>
                      <new:FGetContact>
                         <new:iContactNumber>'.$this->iContactNumber.'</new:iContactNumber>
                      </new:FGetContact>
                   </soapenv:Body>
                </soapenv:Envelope>';
    

    (If someone have the same problem, try var_dump($request) and view source in browser. You will see what a mess PHP did there...)