NAV 2009 R2 Classic Client post inform by API + JSON

Hi,

I am using NAV 2009 R2 classic client, would like to do an API post function to put PO Header and PO Line information to 3rd parties by using API + JSON. May I know how to do it? And how to get the response message from 3rd parties and showing success or error message to user / log into a table for user to check the transmission result.

Thanks!

Answers

  • SanderDkSanderDk Member Posts: 362
    Hi kiyachu,
    I do believe with NAV 2009 you can only do SOAP service
    For help, do not use PM, but use forum instead, perhaps other people have the same question, or better answers.
  • kiyachukiyachu Member Posts: 7
    Thanks, SanderDk

    SOAP service means not API + JSON
    or
    I can carry out API + JSON via SOAP?

    Any details post for that?
    thanks a lot!
  • SanderDkSanderDk Member Posts: 362
    You cannot carry out json, SOAP is based on XML :smile:
    Any details about what?
    Setting up NAV service to run webservice?
    Communication with NAV webservice?
    For help, do not use PM, but use forum instead, perhaps other people have the same question, or better answers.
  • ftorneroftornero Member Posts: 306
    Hello @kiyachu,

    In your NAV version if you publish an WS it is a SOAP one and the data interchanged are XML , but if you want to consume an external WS it could be SOAP/XML or REST/JSON.

    What's it your case ?

    Regards
  • kiyachukiyachu Member Posts: 7
    Thanks SanderDk & ftornero

    The 3rd parties software that I POST information to require REST/JSON.
    So what workaround I can choose with NAV version 2009 SP1?
    Any link I can follow to work the solution out, many thanks for your advise.
  • SanderDkSanderDk Member Posts: 362
    edited 2019-09-24
    I misunderstood your answer
    #delete
    For help, do not use PM, but use forum instead, perhaps other people have the same question, or better answers.
  • ftorneroftornero Member Posts: 306
    Hello @kiyachu,

    If I don't miss anything I think that you need to call a REST API from NAV, so you can do it with somethig like this:

        CREATE(WinHttp);
        WinHttp.Open('POST',url,FALSE);
        WinHttp.SetRequestHeader('Content-Type', 'application/json');
        WinHttp.Send(JsonTxt);
        ResponseStream := WinHttp.ResponseStream;
        ResponseBuffer.READ(ResponseStream);
    

    Where the vars are:
    ResponseStream	InStream		
    ResponseBuffer	BigText
    url	Text		1024
    JsonTxt	Text		1024
    
    WinHttp	Automation	'Microsoft WinHTTP Services, version 5.1'.WinHttpRequest			
    

    If the JSON to send it's bigger than 1024 you need to use some workaround like an XML node text.

    Regards
  • kiyachukiyachu Member Posts: 7
    HI ftornero,

    Thanks for the code, may I have more e.g. where to state the API address, API key?
    For the Post content, as per your suggestion, I use XML node text to store and then converse it to JSON format before send out?
    May I have more code example for reference, many thanks!

  • ftorneroftornero Member Posts: 306
    Hello @kiyachu,

    The API address goes in the url variable.

    If you need to pass the API key it depends of what it's the REST API expecting, this would be an example for HubSpot, but you must check the API documentation to be sure:
    url := 'https://api.hubapi.com/contacts/v1/lists/all/contacts/all?&count=100&hapikey=' +hapikey;
    

    And regarding the JSON part you need to build the structure like this:
      NodeText := XMLDoc.createTextNode('');
      NodeText.appendData('{ "product": {');
      NodeText.appendData( '"sku":"1234567890",');
      NodeText.appendData('"extension_attributes": { "stock_Item": {');
      NodeText.appendData( '"qty": 60');
      NodeText.appendData('},');
      NodeText.appendData('},');
      NodeText.appendData('},');
      NodeText.appendData('}');
    

    Where the vars are:
    Name	DataType	Subtype	Length
    XMLDoc	Automation	'Microsoft XML, v3.0'.DOMDocument	
    NodeText	Automation	'Microsoft XML, v3.0'.IXMLDOMText	
    

    And later on pas the value to the REST API.
    WinHttp.Send(NodeText.nodeValue);
    

    Regards
  • kiyachukiyachu Member Posts: 7
    Hi ftornero,

    I got an error of
    "This Automation variable has not been instantiated.
    You can instantiate it by either creating or assigning it."

    Code :

    IF ISCLEAR(WinHttp) THEN
    CREATE(WinHttp);

    url := 'https://jsonplaceholder.typicode.com/users';
    WinHttp.Open('POST',url,FALSE);
    WinHttp.SetRequestHeader('Content-Type', 'application/json');
    WinHttp.Send(JsonTxt);
    ResponseStream := WinHttp.ResponseStream;
    ResponseBuffer.READ(ResponseStream);


    NodeText := XMLDoc.createTextNode('');
    NodeText.appendData('{ "id": "111",');
    NodeText.appendData( '"name":"A",');
    NodeText.appendData('"username": "X"');
    NodeText.appendData('}');

    WinHttp.Send(NodeText.nodeValue);

    Variable
    Name DataType Subtype Length
    WinHttp Automation 'Microsoft WinHTTP Services, version 5.1'.WinHttpRequest
    NodeText Automation 'Microsoft XML, v3.0'.IXMLDOMText
    XMLDoc Automation 'Microsoft XML, v3.0'.DOMDocument

    I use report to run it.
    Version : NAV 2009 SP21 - Classic client

    Pls comment, thanks!
  • ftorneroftornero Member Posts: 306
    Hello @kiyachu ,

    You need to creaste the XMLDoc before use it.
    CREATE(XMLDoc);
    NodeText := XMLDoc.createTextNode('');
    

    Regards
  • kiyachukiyachu Member Posts: 7
    Hi ftornero,

    No error after adding create XMLDoc. Thanks!

    Now, I would like to know where and how to get the response from server after I post information to server?
    I would like to prompt a message to user for showing success or not and the ID #, how can I get those from response and show it to user as message box in NAV and/or write to a table for user to check whether the post action success or not for that ID#

    Like this I got when I use postman for test of json content

    8gxnqhfzsczk.jpg

  • ftorneroftornero Member Posts: 306
    Hello @kiyachu ,

    After sending the request you can get the response like this:
          ResponseStream := WinHttp.ResponseStream;
    

    Where ResponseStream is a InStream variable.

    Regards.
  • kiyachukiyachu Member Posts: 7
    Hi ftornero,

    How can we read ResponseStream and display it as message or store into a table?
    I add "MESSAGE(FORMAT(ResponseStream))" at the end, but the message box show empty?
    ========================================
    IF ISCLEAR(WinHttp) THEN
    CREATE(WinHttp);

    url := 'https://jsonplaceholder.typicode.com/users';
    WinHttp.Open('POST',url,FALSE);
    WinHttp.SetRequestHeader('Content-Type', 'application/json');
    WinHttp.Send(JsonTxt);
    ResponseStream := WinHttp.ResponseStream;
    ResponseBuffer.READ(ResponseStream);

    CREATE(XMLDoc);
    NodeText := XMLDoc.createTextNode('');
    NodeText.appendData('{ "id": "111",');
    NodeText.appendData( '"name":"A",');
    NodeText.appendData('"username": "X"');
    NodeText.appendData('}');


    WinHttp.Send(NodeText.nodeValue);
    MESSAGE(FORMAT(ResponseStream)); //ADD FOR SHOWING RESPONSE
  • ftorneroftornero Member Posts: 306
    Hello @kiyachu ,

    You could get this InStream variable and fill a BigText with it:
          ResponseBuffer.READ(ResponseStream);
    

    Where ResponseBuffer is the BigText var.

    Later on you can deal with this var to show your message.

    You can also write to a file and read the file to do the same.

    Regards.
  • ChuChuChuChu Member Posts: 4
    Hi ftornero,

    I have followed this post and get it works on sending JSON API under NAV2009SP1 version.

    Now my question is, how can I save the outstream as a text file, so that I can keep a copy on what I have send out (The POST content).

    Many thanks! It is my last step for this customization!!!!!

  • ftorneroftornero Member Posts: 306
    Hello @ChuChu ,

    You can do something like this:
        i := 0;
        Fich.CREATE(Path+'data.json');
        WHILE i <= NodeText.length DO BEGIN
          Fich.WRITE(NodeText.substringData(i, 1));
          i := i + 1;
        END;
        Fich.CLOSE;
    

    Where the variables are:

    i is an Integer

    Fich is a FILE

    Path is a Text with the Path where you want to create the output file.

    Regards
  • ChuChuChuChu Member Posts: 4
    Hi ftornero,

    Yes, it works fine for your coding.
    Thank you very much!!!!

    Regards
  • VishalAgVishalAg Member Posts: 1
    Hi @ftornero ,

    I wanted to know if there is a way to send few rows and columns of a table based on filter through it instead of single value. If so, please help me with some example.

    Thank You
  • ftorneroftornero Member Posts: 306
    Hello @VishalAg

    Yes, you can send the information you want but it depends on what the web service you are connected is expecting.

    Regards.
Sign In or Register to comment.