NAV Web Services - SOAP Envelope Parameters

raven44raven44 Member Posts: 85
edited 2010-01-04 in NAV Three Tier
Hi,

I'm calling a Web Service from within NAV as follows:
XMLHttp.open('POST',WSURL + TargetCompany + PublishedObjectPath,0,
  WSAccount,WSPassword);

XMLHttp.setRequestHeader('Content-Type', 'text/xml; charset=utf-8');
XMLHttp.setRequestHeader('SOAPAction',ObjectFunction);
XMLHttp.setTimeouts(10000,10000,10000,100000);
XMLHttp.send(
  '<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">' +
  '<soap:Body><' + ObjectFunction + ' xmlns="urn:microsoft-dynamics-schemas' + PublishedObjectPath + '">' +
  '<Parm1>'+Parm1+'</Parm1>' +  // Parameter 1
  '<Parm2>'+Parm2+'</Parm2>' +  // Parameter 2
  '</' + ObjectFunction + '></soap:Body></soap:Envelope>');
XMLDoc.async := FALSE;
XMLDoc.load(XMLHttp.responseBody);

The XML doc its creating looks something like this:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"&gt;
<soap:Body>
<MyMessage xmlns="urn:microsoft-dynamics-schemas/Codeunit/NAVWebServices">
<Parm1>TEST</Parm1>
<Parm2>Test Description</Parm2>
</MyMessage>
</soap:Body>
</soap:Envelope>


The function I'm calling is as follows (Note this is just a test function to work out how to pass parameters with the following WS call - I know this actual code could be executed with the CHANGECOMPANY code):
MyMessage(Parm1 : Code[20];Parm2 : Text[50])

Item.INIT;
Item."No." := Parm1;
Item.Description := Parm2;
Item.INSERT;

Unfortunately the error I'm getting is:
- <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"&gt;
- <s:Body>
- <s:Fault>
<faultcode xmlns:a="urn:microsoft-dynamics-schemas/error">a:Microsoft.Dynamics.Nav.Service.WebServices.ServiceBrokerException</faultcode>
<faultstring xml:lang="en-NZ">Parameter parm1 in method MyMessage in service NAVWebServices is null!</faultstring>
- <detail>
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">Parameter parm1 in method MyMessage in service NAVWebServices is null!</string>
</detail>
</s:Fault>
</s:Body>
</s:Envelope>


Does anyone have any ideas on what could be wrong?

I've tried adding 'ws:' in certain tags as per another post but no luck on it.

Thanks in advance.

Answers

  • iceborgiceborg Member Posts: 67
    Try with "<parm1>" & "<parm2>" NOT "<Parm1>" & "<Parm2>" in your soap request :lol:
  • raven44raven44 Member Posts: 85
    Gave this a go and received the same error message:

    <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"&gt;
    <s:Body>
    <s:Fault>
    <faultcode xmlns:a="urn:microsoft-dynamics-schemas/error">a:Microsoft.Dynamics.Nav.Service.WebServices.ServiceBrokerException</faultcode>
    <faultstring xml:lang="en-NZ">Parameter parm1 in method MyMessage in service NAVWebServices is null!</faultstring>
    <detail>
    <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">Parameter parm1 in method MyMessage in service NAVWebServices is null!</string>
    </detail>
    </s:Fault>
    </s:Body>
    </s:Envelope>


    This is how the new xml doc looked:
    <?xml version="1.0" encoding="utf-8"?>
    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"&gt;
    <soap:Body>
    <MyMessage xmlns="urn:microsoft-dynamics-schemas/Codeunit/NAVWebServices">
    <parm1>TEST</parm1>
    <parm2>Test Description</parm2>

    </MyMessage>
    </soap:Body>
    </soap:Envelope>

    I also intend to think its something to do with formatting (based on other posts and forums I've read), but what seems strange is that its stating my parameter values are null :?

    Any other ideas?
  • iceborgiceborg Member Posts: 67
    I am using something like similar to this from NAV and it works,


    SendXML(VAR XMLOUT : Automation "'Microsoft XML, v6.0'.DOMDocument") Status : Integer
    //Wraps the outgoing XML dataset in Soap and submit it to webservice
    //(the webservice called is a NAV Codeunit with a function 'receiveandreply' exposed as a webservice named 'wsxml' and the method then is 'Receiveandreply')

    IF ISCLEAR(XMLHTTP) THEN
    CREATE(XMLHTTP);

    NAVCompanyURL := 'CRONUS%20International%20Ltd.'; //Change this to the company name for which you expose the ws.
    navwsurl := 'http://localhost:7047/DynamicsNAV/WS';
    nsp := 'urn:microsoft-dynamics-schemas/codeunit/wsxml';
    soapmethod := 'Receiveandreply';
    surl := navwsurl + '/' + NAVCompanyURL +'/Codeunit/wsxml';
    soapaction := nsp + '/' + soapmethod;

    TempBlob.Blob.CREATEOUTSTREAM(OutS);
    OutS.WRITETEXT('<?xml version="1.0" encoding="utf-8"?>');
    OutS.WRITETEXT('<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' +
    ' xmlns:xsd="http://www.w3.org/2001/XMLSchema&quot; xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">');
    OutS.WRITETEXT('<soap:Body><' + soapmethod + ' xmlns="' + nsp + '">');
    OutS.WRITETEXT('<xmldata><![CDATA[');
    XMLOUT.save(OutS); //Saving the xml dataset into the request
    OutS.WRITETEXT(']]></xmldata><result></result>');
    OutS.WRITETEXT('</' + soapmethod + '></soap:Body></soap:Envelope>');

    TempBlob.Blob.CREATEINSTREAM(InS);
    CREATE(TmpXMLReq);

    TmpXMLReq.load(InS);
    TmpXMLReq.save('C:\temp\request.xml'); //Saving the complete soap request for reference


    //XMLHTTP.open('POST',surl,0); //For Classic Client this is enough
    XMLHTTP.open('POST',surl,FALSE,'DOMAIN\User','PasswordInClearText'); //From RTC We need to set the Credentials as we execute under NST Credentials ?


    XMLHTTP.setRequestHeader('Content-type','text/xml');
    XMLHTTP.setRequestHeader('SOAPAction',soapaction);
    XMLHTTP.send(TmpXMLReq); //Sending the Request to WebService

    CREATE(TmpXmlReply);

    TmpXmlReply.load(XMLHTTP.responseXML); // Loading reply from Webservice and saving it for reference
    TmpXmlReply.save('C:\temp\response.xml');
    Status := XMLHTTP.status;

    Hope it helps,
  • raven44raven44 Member Posts: 85
    Firstly, thanks for the assistance!

    I've implemented the logic you specified (just not 100% sure if I've done the <![CDATA ]]> correctly as I dont have the initial XML document - so I've just written in the parameters through the text constants.

    <?xml version="1.0" encoding="utf-8" ?>
    <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance&quot; xmlns:xsd="http://www.w3.org/2001/XMLSchema&quot; xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"&gt;
    <soap:Body>
    <MyMessage xmlns="urn:microsoft-dynamics-schemas/Codeunit/NAVWebServices">
    <xmldata>
    <![CDATA[ <Parm1>TEST</Parm1><Parm2>Test Description</Parm2>
    ]]>
    </xmldata>
    <result />
    </MyMessage>
    </soap:Body>
    </soap:Envelope>


    I received the same error message with the above logic: Parameter parm1 in method MyMessage in service NAVWebServices is null!

    Note: I did try it with the following:
    ..
    <![CDATA[ <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><MyMessage xmlns="urn:microsoft-dynamics-schemas/Codeunit/NAVWebServices"><parm1>TEST</parm1><parm2>Test Description</parm2></MyMessage></soap:Body></soap:Envelope>
    ]]>
    ..

    But again - I may have the CDATA information incorrect.
  • iceborgiceborg Member Posts: 67
    That is a bit funny :-), I just runned this again and it works fine.

    Are you relly sure the name of your parameters is exactly right? - If your WS is a NAV Exposed Function in a Codeunit,
    just remember that allthough you in NAV name your Parameter "Parm1" it will be exposed as "parm1" to comply with .Net "dromedary case" for parameters.
    That gave me some griefs in the beginning ](*,)
  • iceborgiceborg Member Posts: 67
    and for the record you don't need that CDATA stuff, that is just needed in case you are passing content in a parameter that contains "funky" characters like ' " and others, simply explained.
  • iceborgiceborg Member Posts: 67
    another thing there, you got it a bit wrong with the CDATA thing, it is supposed to be inside a parameter tag.
    and the tag <xmldata> is in my case the parameter in my NAV Codeunit receiving the request (just like your <parm1> & <parm2>)
    So if you want to pass something that can contain a lot or funky characters in a parameter named "parametername" of type BigText Like a XML Document)for example you do something like this: <parametername><![CDATA["Here goes'" the 'I^%$ Stuff"]]></parametername> if you just have plain test or integers you don't need the CDATA things.
  • ara3nara3n Member Posts: 9,255
    use soapUI to see how the xml should look like.

    Then save your xmlfile you generate and compare them.
    Ahmed Rashed Amini
    Independent Consultant/Developer


    blog: https://dynamicsuser.net/nav/b/ara3n
  • raven44raven44 Member Posts: 85
    Hi All,

    Hope you had a good Christmas and happy New Year!

    Big thanks to iceborg and ara3n.
    With your help I've gotten a solution to this issue.

    The resultant XML file looks like this:
    <?xml version="1.0" encoding="utf-8"?>
    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/&quot; xmlns:nav="urn:microsoft-dynamics-schemas/codeunit/NAVWebServices">
    <soap:Header/>

    <soap:Body>
    <nav:MyMessage>
    <nav:parm1>TEST</nav:parm1>
    <nav:parm2>Test Description</nav:parm2>
    </nav:MyMessage>
    </soap:Body>
    </soap:Envelope>

    I've bolded the changes but basically had to declare 'nav' in the soap:Envelope rather than the soap:Body section.
    Then I also added the Header section (although this is not required and works without it).

    Thanks again!
  • sb_sb_ Member Posts: 5
    10 Years later and your solution worked for me. Thanks.
  • rsgilbertrsgilbert Member Posts: 3
    edited 2021-12-21
    Very helpful indeed. I would like to point out that one of the reasons for the error was because he was capitalizing the first letter of "codeunit" in his xmlns. It should be "xmlns:nav="urn:microsoft-dynamics-schemas/codeunit/NAVWebServices" and not "xmlns:nav="urn:microsoft-dynamics-schemas/codeunit/NAVWebServices".

    Here is a complete HTTP SOAP request:

    POST /DynamicsNAV90/WS/inv3/Codeunit/SGMSUtil HTTP/1.1
    Host: JUNIT:7067
    Content-Type: text/xml;
    SOAPAction: "urn:microsoft-dynamics-schema/codeunit/SGMSUtil:Login"
    Content-Length: 322

    <soap:Envelope
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/&quot;
    >
    <soap:Header />
    <soap:Body>
    <Login xmlns="urn:microsoft-dynamics-schemas/codeunit/SGMSUtil">
    <email>Jonathan</email>
    <password>Ate</password>
    </Login>
    </soap:Body>
    </soap:Envelope>
Sign In or Register to comment.