I have been using SOAP services over the last years.  Only recently the RESTful web services have become more and more popular in my integration work.  Wikipedia says:

In computing, Representational State Transfer (REST) is a software architecture style for building scalable web services. REST gives a coordinated set of constraints to the design of components in a distributed hypermedia system that can lead to a higher performing and more maintainable architecture.

RESTful systems typically, but not always, communicate over the Hypertext Transfer Protocol with the same HTTP verbs (GET, POST, PUT, DELETE, etc.) which web browsers use to retrieve web pages and to send data to remote servers. REST interfaces usually involve collections of resources with identifiers, for example /people/paul, which can be operated upon using standard verbs, such as DELETE /people/paul.

As we are used to XML as the body for our SOAP messages we can also use XML as the body for a RESTful web service.  I just finished writing a code to communicate with Azure from NAV.  This communication was using RESTful web services and XML.

So, what is JSON?  Wikipedia says:

JSON, (canonically pronounced /ˈdʒeɪsən/ JAY-sən; sometimes JavaScript Object Notation), is an open standard format that uses human-readable text to transmit data objects consisting of attribute–value pairs. It is the primary data format used for asynchronous browser/server communication (AJAJ), largely replacing XML (used by AJAX).

Although originally derived from the JavaScript scripting language, JSON is a language-independent data format. Code for parsing and generating JSON data is readily available in many programming languages.

The JSON format was originally specified by Douglas Crockford. It is currently described by two competing standards, RFC 7159 and ECMA-404. The ECMA standard is minimal, describing only the allowed grammar syntax, whereas the RFC also provides some semantic and security considerations. The official Internet media type for JSON is application/json. The JSON filename extension is .json.

With JSON it is possible to deliver similar data structure as with XML.  JSON on the other hand requires a much less metadata.  Here is an example JSON from Wikipedia:

[code lang=”javascript”]{
"firstName": "John",
"lastName": "Smith",
"isAlive": true,
"age": 25,
"address": {
"streetAddress": "21 2nd Street",
"city": "New York",
"state": "NY",
"postalCode": "10021-3100"
},
"phoneNumbers": [
{
"type": "home",
"number": "212 555-1234"
},
{
"type": "office",
"number": "646 555-4567"
}
],
"children": [],
"spouse": null
}[/code]

There is not a good support for JSON in native .NET from Microsoft.  However, with Visual Studio, Microsoft installs an external DLL in to the folder “C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\PrivateAssemblies”

Newtonsoft

With this Json.NET in Dynamics NAV Add-ins folder we now have some way to handle JSON files.  Using this Add-in I created a NAV Codeunit to manage JSON text.

This Codeunit contains functions to build a JSON document, like

[code lang=”csharp”]
StartJSon;
AddToJSon(‘newssn’,CompanyInformation."Registration No.");
AddToJSon(‘billtossn’,BillToCustNo);
AddToJSon(‘newcompanyname’,CompanyInformation.Name);
AddToJSon(‘newemail’,CompanyInformation."E-Mail");
AddToJSon(‘register_einvoice’,EInvoiceEnabled);
AddToJSon(‘register_supdoc’,SupDocEnabled);
AddToJSon(‘register_natreg’,NRLookupEnabled);
EndJSon;
Json := Json.Copy(GetJSon);[/code]

A function to import values from a JSON document to a temporary table, like

[code lang=”csharp”]
ReadJSon(String,TempPostingExchField);

WITH TempPostingExchField DO BEGIN
SETCURRENTKEY("Line No.","Column No.");
IF FIND(‘-‘) THEN REPEAT
SETRANGE("Column No.","Column No.");
InsertFileDetails(TempPostingExchField,WebServiceURL);
FINDLAST;
SETRANGE("Column No.");
UNTIL NEXT = 0;
END;[/code]

Or just a simple way to return a single value from a simple JSON string, like

[code lang=”csharp”]FileName := GetValueFromJsonString(String,’filename’);[/code]

With these functions NAV should be able to handle JSON files without any problems.

Now you can add JSON handling to your arsenal.

Json Codeunit and required add-ins

57 thoughts on “JSON meets NAV

  1. Dave Machanick says:

    Gunnar,
    Thanks for the very useful blog.
    Since JSON download has support for .net back to 2.0, does this mean it is supported in Visual Studio 2008 and NAV2009SP1/R2?
    Also, the login to a JSON site puzzles me. Can we use this for the initial login as well?

  2. I am not following you Dave. JSON is just a string so if you are not able to use the Newtonsoft.Json.dll you could manually handle the string in C/AL.
    I have treated login with http headers and also with basic authentication. In Azure I even had to create an authorization string. I don’t think that a JSON site has any predefined authorization that must be used. What is your example ?

  3. Dave Machanick says:

    API requests are JSON. They are sent to the API using a HTTP connection over SSL using all four verbs (GET, PUT, POST and DELETE).
    Authentication

    Calls to the API are managed using HTTP authentication (Only “Basic” is currently supported). Every request must include the Authorisation HTTP header containing username and password. The username is your Partner ID and your password is your signature hash.
    Example:
    curl -H ‘Accept: application/json’ -H ‘Content-Type: application/json’ \
    -u 123:XXXXXXXXXXXXXXXXXXXXXX \
    -d ‘…JSON request object goes here…’ https://gapi.checkmend.com/{method}
    ——
    The curl example does not help me – maybe if I was starting from Unix.
    It looks like it should be easy if I knew how to translate it
    I also have to generate a signature hash.
    It looks like they also expect recommend using a curl client library – which appears to me to be more than JSON.

    Do you think from the above that this is way beyond JSON or am I just getting confused with the terminology?

    1. curl is just a http client, similar to wget in windows. You can add the headers to the httpwebrequest object by using HttpWebRequest.Headers.Add(Key,Value); You should find what you need to build the authorization header in dotnet library System.Security.Cryptography and System.Convert in mscorlib.

  4. Tino Ruijs says:

    Hi Gunnar,

    Thanks for this blog!
    I failed to register the .dll’s. I used “Run as administrator” for cmd-box.
    I’ve tried it in System32 and SysWOW64, but both give the same error:

    [Window Title]
    RegSvr32

    [Content]
    The module “NAVWebRequest.dll” was loaded but the entry-point DllRegisterServer was not found.

    Make sure that “NAVWebRequest.dll” is a valid DLL or OCX file and then try again.

    [OK]

    Do you know what I’m doing wrong?

    Thanks in advance.

    With kind regards,

    Tino Ruijs

    1. Hi Tino.

      No need to register the NAVWebRequest.dll file. Just put it into the server add-ins folder.

  5. Tino Ruijs says:

    Hi Gunnar,

    Thanks for the reply.
    I’ve put the files in a folder called Json in directories “C:\Program Files\Microsoft Dynamics NAV\71\Service\Add-ins” and “C:\Program Files\Microsoft Dynamics NAV\71\Service\Add-ins”.

    Now when I open the Development Enviroment and try to add a variable of DataType DotNet in a codeunit I get an error

    “—————————
    Microsoft Dynamics NAV Development Environment
    —————————
    Could not load type ”.
    —————————
    OK
    —————————

    ” when selecting the NAVWebRequest from the ” Dynamics NAV” in the “Assembly List”.

    I don’t know what I’m doing wrong…

    1. Tino Ruijs says:

      It seems to be a server-problem because I don’t succeed selecting other dll’s.
      I’ll look into it.

      1. Tino Ruijs says:

        It probably has something to do with Security on the copied dll-file. I need to unblock the file.
        I found out some windows-versions/setup mark the downloaded zip as not secure.
        So I had to go to the properties of the zip-file and click “Unblock” and then ok. Then extracted the zip-file.
        Now it works fine! 🙂

  6. Shan says:

    Hello,
    Do I need to add .dll into addin folder . Because I have 20 LS POS with separate database. So each and every pos terminal I need to add the .DLL Is there any way ?

    1. You need the .dll in the addin folder of every server that is reading a json file. There is a way to automatically download and install the .dll. I have a blog entry about that.

  7. AlexRichter says:

    Hi Gunnar,
    thank you for this very helpful Blogpost.

    Im struggling with basic authentication.
    I created a Demo Scenario where I try to send a Post Request to a Regeust Bin.

    Here is my Demo Function:

    JSONManagement.StartJSon;
    JSONManagement.AddToJSon(‘transition’,41);
    JSONManagement.EndJSon;
    JSONManagement.UploadJSon(‘http://requestb.in/XXX’,’UserName’,’Password’,Json);

    The Post itself works and the Repsonse looks also nice but im missing the Authentification String in the request Header.
    How can i manage Basic Authentification?

    Thanks for your Feedback,

    Alex

    1. Hi Alex

      Basic authentication you do on the HttpRequest object.

      AddCredentials(UserName : Text;Password : Text)
      Credential := Credential.NetworkCredential;
      Credential.UserName := UserName;
      Credential.Password := Password;
      HttpWebRequest.Credentials := Credential;

      1. Pankaj Arya says:

        Hi Gunnar,

        I just read this blog, it’s a great help. I try to implement this, but when DoWebRequest() is call and NAVWebRequest.dll is used, my rtc service got stooped and i got the error for this. Please explain?

        1. It is always possible that a downloaded dll file could be blocked by the operating system. I would start by looking at that Pankaj

      2. AlexRichter says:

        Hey Gunnar,

        thank you for the Feedback.
        Unfortunately your answer didnt helped me.

        my understanding is that the Code you wrote is part the same as the CreateCredentials function from your Sample.

        If i call the UploadJson Function with UserName and Password:

        JSONManagement.UploadJSon(‘http://requestb.in/XXX’,’UserName’,’Password’,Json);

        it will call the CreateCredentials Function. with UserName and Passwort.

        Somehow i still miss the Authentification part in the header.

        Im not so super used to .net Variables in NAV so i think that im missing something here?

        1. Hi Alex
          If you are using my UploadJSon function, then that function does not insert any authentication header. Authentication is usually either in the header or as basic authentication (could say as a part of the url). Each service may have different ways of authentication. I am for example talking to Azure API and that has all the authentication in the http request header.

  8. Michael Hartmann says:

    Hi Gunnar.
    SUPER post!!
    I have a problem with compiling your exampel CU 🙁
    I have copyied the two DLL’s to th Add-in folder, both in service directory and in the client directory, but still i get the following error:

    Could not load type ‘Newtonsoft.Json.JsonTextWriter.’Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed”.

    There is not installed Visual Studio on the machine, so Newtonsoft.Json.dll is only present in the add-in folders.
    I have tryied to register the DLL, but that is not possible.
    Do you have any suggestions?

    /Michael

    1. Michael Hartmann says:

      Solved the problem by downloading the newest version of Newtonsoft.Json.dll from http://www.newtonsoft.com/json
      /Michael

      1. Michael Doheny says:

        Hello Michael,
        I received the same error. I think I downloaded the latest .dll. Could you detail what you did after download? It looks like the Assembly list is still looking at the first .dll
        Thank you

        1. Michael Doheny says:

          There were a number of Newtonsoft.Json.dll filles. I copied the one from the Net45 folder and pasted it to: C:\Program Files\Microsoft Dynamics NAV\90\Service\Add-ins

          1. gwaindepyk says:

            Hi Michael, I’m facing the same challenge with registering the .dll file, did you manage to solve it? if yes then How?

      2. gwaindepyk says:

        Hi Michael, I’m facing the same challenge with registering the .dll file, I have downloaded the latest dll, put it in the ad ins folder. but I am still getting the error you mentioned, how exactly did you manage to resolve it. thank you

  9. Undy says:

    Hello Gunnar,
    How can I pass values between Json type and C/AL using this codeunit?
    I have external assembley with Json types and need to set|get values between them.
    BridgePosAPI.put() class need to get amount, cust_name….fields value from NAV
    BridgePosAPI.send() class need to returns into NAV
    How can I use this Json type in NAV?

    Regards,
    Undy

    1. Yes, you can both read and write Json format with the help of this codeunit.

  10. uugii0602 says:

    How to write text type into JSon string?
    I dont understand above example because I dont have any experience with it.

    What is type Json below part of code?
    Json := Json.Copy(GetJSon)

    1. Json is dot net class system.string in mscorlib.dll

  11. uugii0602 says:

    Where is InsertFileDetails() functions? I didnt found from this codeunit

  12. Michael Hartmann says:

    Hi Gunnar.
    Is it possible for you to demonstrate how to make the “phoneNumbers” part of the below Wikipedia example in NAV code?
    That would be much appreciated 🙂
    /Michael

    {
    “firstName”: “John”,
    “lastName”: “Smith”,
    “isAlive”: true,
    “age”: 25,
    “address”: {
    “streetAddress”: “21 2nd Street”,
    “city”: “New York”,
    “state”: “NY”,
    “postalCode”: “10021-3100”
    },
    “phoneNumbers”: [
    {
    “type”: “home”,
    “number”: “212 555-1234”
    },
    {
    “type”: “office”,
    “number”: “646 555-4567”
    }
    ],
    “children”: [],
    “spouse”: null
    }

    1. Agree with Michael, would be really helpful to have a NAV example of code of how to treat the structures like the phone number of the Wiki.

      Daniele

      1. Patryk Banach says:

        That would be so helpful…

        1. WITH JSonMgt DO BEGIN
          StartJSon;
          AddToJSon(‘firstName’,’John’);
          AddToJSon(‘lastName’,’Smith’);
          AddToJSon(‘isAlive’,TRUE);
          AddToJSon(‘age’,25);
          AddJSonBranch(‘Address’);
          AddToJSon(‘streetAddress’,’21 2nd Street’);
          AddToJSon(‘city’,’New York’);
          AddToJSon(‘state’,’NY’);
          AddToJSon(‘postalCode’,’10021-3100′);
          EndJSonBranch;
          StartJSonArray(‘phoneNumbers’);
          StartJSon;
          AddToJSon(‘type’,’home’);
          AddToJSon(‘number’,’212 555-1234′);
          EndJSon;
          StartJSon;
          AddToJSon(‘type’,’office’);
          AddToJSon(‘number’,’646 555-4567′);
          EndJSon;
          EndJSonArray;
          StartJSonArray(‘children’);
          EndJSonArray;
          AddToJSon(‘spouse’,’null’);
          EndJSon;
          JSon := GetJSon;
          END;

          1. Patryk Banach says:

            It doesn’t make sense to me because StartJSonArray doesn’t require any parameter…:

            StartJSonArray()
            IF ISNULL(StringBuilder) THEN
            Initialize;
            JsonTextWriter.WriteStartArray;

            In this case it looks like I’m missing something? but I have figured out it (a little bit around…) by myself to make it working.

            But still thank you for your response.

          2. Bert says:

            Hi,
            As Patryk says:
            “It doesn’t make sense to me because StartJSonArray doesn’t require any parameter…:
            StartJSonArray()
            IF ISNULL(StringBuilder) THEN
            Initialize;
            JsonTextWriter.WriteStartArray;”

            I’m currently stuck on this. Please enlighten me what i’m doing wrong?

          3. Add a parameter to StartJsonArray to write the property name similar to StartJsonBranch

          4. Bert says:

            Thank you for your reply!
            I allready came to that solution by myself, i felt pretty stupid 🙂
            I also had to create a “StartJsonObject” and “EndJsonObject” function
            (JSonTextWriter.WriteStartObject; and JSonTextWriter.WriteEndObject;)

          5. Ashu garg says:

            Thanks Gunnar, very helpful post and with above code change can export sales header and lines in JSON format

  13. Michael Doheny says:

    There were a number of Newtonsoft.Json.dll filles. I copied the one from the Net45 folder and pasted it to: C:\Program Files\Microsoft Dynamics NAV\90\Service\Add-ins

  14. Yasith Udawatte says:

    Hello Gunnar,

    I am trying to pass a Json request to an external API. When I try to pass the request using UploadJson(), it gives the following error;

    System.Net.WebException: The remote server returned an error: (415) Unsupported Media Type.
    at System.Net.HttpWebRequest.GetResponse()
    at NAVWebRequest.NAVWebRequest.doRequest(HttpWebRequest& WebRequest, WebException& WebException, WebRespons

    I add the following piece of code to CreateWebRequest funtion but it didn’t work;
    HttpWebRequest.MediaType := ‘application/json’;

    What could be the reason?

    1. Hi Yasith

      I always use ContentType, not MediaType.

  15. Nikolay Topalov says:

    Thank you for good post !

  16. Nikolay Topalov says:

    Hi Gunnar,
    It is really useful your post and make life a bit easier for handling JSON. However I come up to a JSON which I get as a response of a web service that I was not able to handle.

    [{
    “Customer” : {
    “Name” : “FirstName”,
    “Company” : “company”,
    “Email” : “FirstName.LastName@company.net”,
    “CountryId” : 16
    },
    “Credentials” : {
    “Username” : “username”,
    “Password” : “password”,
    “EPLI” : “cb66-ddce-42e9-8fb2-b3532ae6bd14”,
    “LicenseKey” : “A4N9-5R2J”,
    “PublicLicenseKey” : “3K9”,
    “CommonTag” : “3d4a2-4900-bca9-143c7bcc34c0”
    },
    “LicenseInfo” : {
    “Product” : “111”,
    “Quantity” : 10,
    “PurchaseType” : “New”,
    “PurchaseTypeId” : 1,
    “ExpirationDate” : “10/10/2017”,
    “State” : “Active”,
    “PublicResellerId” : “”,
    “PartnerId” : 99,
    “Note” : “Test”,
    “ChannelId” : 14,
    “BatchBased” : false,
    “UpdateTypeId” : 1,
    “DealCode” : “”,
    “ActivationToken” : null,
    “SuppressExpirationMessage” : null,
    “ActivationDate” : null
    },
    “Price” : {
    “DistributorPrice” : “240.00”,
    “SystemPrice” : “364.50”,
    “ResellerPrice” : “0”,
    “Currency” : “EUR”,
    “DiscountCode” : “0”
    },
    “BundleProduct” : {
    “Product” : “1500”,
    “Quantity” : 10
    },
    “ParentLicense” : null,
    “ProductInfo” : null,
    “SystemInfo” : {
    “CreatedDate” : “10/13/2016 08:27:15.421”,
    “CreatedUserId” : 217,
    “CanceledDate” : null,
    “CanceledUserId” : null,
    “ModifiedDate” : “10/13/2016 08:27:15.421”,
    “ModifiedUserId” : 217
    },
    “AuxilliaryParams” : [],
    “LicenseFiles” : [{
    “Name” : “ERt.lic”,
    “Code” : “Item32”,
    “FileContent” : “ACfSraPrREAn1TGdPq7bzwWFtXIrhrPnZDKw9yi”
    }
    ],
    “LicenseAdministrator” : {
    “Password” : “ccXTX87uTp”,
    “Email” : “FirstName.LastName@company.net”
    },
    “ProductActivation” : null,
    “Invoicing” : null
    }, {
    “Customer” : {
    “Name” : “FirstName”,
    “Company” : “company”,
    “Email” : “FirstName.LastName@company.net”,
    “CountryId” : 16
    },
    “Credentials” : {
    “Username” : “92202”,
    “Password” : “u9vhm”,
    “EPLI” : “e9fec6e3b833”,
    “LicenseKey” : “DJKF-5R2J”,
    “PublicLicenseKey” : “333-365-XK9”,
    “CommonTag” : “3d4a2e48-dba7”
    },
    “LicenseInfo” : {
    “Product” : “810”,
    “Quantity” : 1,
    “PurchaseType” : “New”,
    “PurchaseTypeId” : 1,
    “ExpirationDate” : “10/10/2017”,
    “State” : “Active”,
    “PublicResellerId” : “”,
    “PartnerId” : 22,
    “Note” : “Test”,
    “ChannelId” : 14,
    “BatchBased” : false,
    “UpdateTypeId” : 1,
    “DealCode” : “”,
    “ActivationToken” : null,
    “SuppressExpirationMessage” : null,
    “ActivationDate” : null
    },
    “Price” : {
    “DistributorPrice” : “80.00”,
    “SystemPrice” : “121.50”,
    “ResellerPrice” : “0”,
    “Currency” : “EUR”,
    “DiscountCode” : “0”
    },
    “BundleProduct” : {
    “Product” : “15000”,
    “Quantity” : 10
    },
    “ParentLicense” : null,
    “ProductInfo” : null,
    “SystemInfo” : {
    “CreatedDate” : “10/13/2016 08:27:15.421”,
    “CreatedUserId” : 217,
    “CanceledDate” : null,
    “CanceledUserId” : null,
    “ModifiedDate” : “10/13/2016 08:27:15.421”,
    “ModifiedUserId” : 217
    },
    “AuxilliaryParams” : [],
    “LicenseFiles” : [{
    “Name” : “FileSecurity.lic”,
    “Code” : “Item32”,
    “FileContent” : “gNUUklORyIgVkFMVUU9IkVylD8/uw==”
    }
    ],
    “LicenseAdministrator” : {
    “Password” : “c87uTp”,
    “Email” : “FirstName.LastName@company.net”
    },
    “ProductActivation” : null,
    “Invoicing” : null
    }, {
    “Customer” : {
    “Name” : “FirstName”,
    “Company” : “company”,
    “Email” : “FirstName.LastName@company.net”,
    “CountryId” : 16
    },
    “Credentials” : {
    “Username” : “411”,
    “Password” : “emj”,
    “EPLI” : “9bf2-10329f369fff”,
    “LicenseKey” : “DJKF-5R2J”,
    “PublicLicenseKey” : “333-365-XK9”,
    “CommonTag” : “3d4a2e48-dba7-4900”
    },
    “LicenseInfo” : {
    “Product” : “710”,
    “Quantity” : 5,
    “PurchaseType” : “New”,
    “PurchaseTypeId” : 1,
    “ExpirationDate” : “10/10/2017”,
    “State” : “Active”,
    “PublicResellerId” : “”,
    “PartnerId” : 22,
    “Note” : “Test”,
    “ChannelId” : 14,
    “BatchBased” : false,
    “UpdateTypeId” : 1,
    “DealCode” : “”,
    “ActivationToken” : null,
    “SuppressExpirationMessage” : null,
    “ActivationDate” : null
    },
    “Price” : {
    “DistributorPrice” : “80.00”,
    “SystemPrice” : “121.50”,
    “ResellerPrice” : “0”,
    “Currency” : “EUR”,
    “DiscountCode” : “0”
    },
    “BundleProduct” : {
    “Product” : “1500”,
    “Quantity” : 10
    },
    “ParentLicense” : null,
    “ProductInfo” : null,
    “SystemInfo” : {
    “CreatedDate” : “10/13/2016 08:27:15.421”,
    “CreatedUserId” : 217,
    “CanceledDate” : null,
    “CanceledUserId” : null,
    “ModifiedDate” : “10/13/2016 08:27:15.421”,
    “ModifiedUserId” : 217
    },
    “AuxilliaryParams” : [],
    “LicenseFiles” : [{
    “Name” : “urity.lic”,
    “Code” : “NOD32”,
    “FileContent” : “CeOLfgEzZ3tXOp0okpTVZCB85NBq4=”
    }
    ],
    “LicenseAdministrator” : {
    “Password” : “c87uTp”,
    “Email” : “FirstName.LastName@company.net”
    },
    “ProductActivation” : null,
    “Invoicing” : null
    }
    ]

    /Sorry for the long text 🙂 /

    The ReadJSon function failed with the following message “The Data Exch. Field already exists. Identification fields and values: Data Exch. No.=’4′,Line No.=’1′,Column No.=’0′,Node ID=’.LicenseFiles.ModifiedUserId.Name'”. I think because there is nested second array after LicenseFile which has objects inside and the ColumnNo is not updated correctly after it.

    I made a small adjustments on ReadJSon function which worked for me.

    FirstChange>>

    ……
    ……
    JsonTextReader.TokenType.CompareTo(JsonToken.StartArray) = 0 :
    BEGIN
    InArray[JsonTextReader.Depth + 1] := TRUE;
    //ColumnNo := 0; //ntopalov disable
    ArrayDepth += 1; //ntopalov count the ArrayDepth
    END;
    ……
    ……

    JsonTextReader.TokenType.CompareTo(JsonToken.EndArray) = 0 :
    BEGIN
    InArray[JsonTextReader.Depth + 1] := FALSE;
    ArrayDepth -= 1; //ntopalov
    END;
    JsonTextReader.TokenType.CompareTo(JsonToken.EndObject) = 0 :
    IF JsonTextReader.Depth > 0 THEN
    IF InArray[JsonTextReader.Depth] THEN //ColumnNo += 1;
    //ntopalov begin
    IF ArrayDepth = 1 THEN
    ColumnNo += 1;
    //ntopalov end
    …….
    …….

    Maybe you can come up with more smartest solution.

    Appreciate your reply!

    Kind Regards,
    Nikolay

    1. Roman Hoberniuk says:

      Gunnar,
      thanks for your great post )

      Nikolay,
      tested your code – variable ArrayDepth need to be strictly defined for each json file.
      The problem lays in multiple objects, having similar indentation, and each of them contains arrays.
      Possible universal solution would be to check existing records in temp table for duplicates before insert:

      TempPostingExchField.RESET;
      TempPostingExchField.SETRANGE(“Posting Exch. No.”,PostExchNo);
      TempPostingExchField.SETRANGE(“Column No.”,ArrayNo);
      TempPostingExchField.SETRANGE(“Node ID”,PropertyName);
      IF TempPostingExchField.FINDLAST THEN
      LineNo := TempPostingExchFieldR.”Line No.” + 1;

      and use LineNo as unique object identifier in further parsing. To optimize this check, we could add this code not for all values, but on object start.

      Another problem I attended is about array values.
      A temporary solution is to add them directly in one field with comma:
      IF NOT INSERT THEN BEGIN
      IF GET(“Posting Exch. No.”,”Line No.”,”Column No.”,”Node ID”) THEN
      IF (Value ValueV) THEN
      IF NOT (STRLEN(Value) + STRLEN(ValueV) + 1 > MAXSTRLEN(Value)) THEN BEGIN
      Value += ‘,’ + ValueV; // add comma separated value array
      MODIFY;
      END;
      END;

      Thanks for attention.

  17. manish says:

    Great Post Gunnar,

    Need one help:

    how to add a formatkey before start of the body like

    format=json&data=

    {
    “Entry No”: “345667”,
    “Entry_id”: 29
    }

    Please suggest the code in NAV to handle this

    1. I would just do it manually to the string created by jsonstreamwriter

      1. manish says:

        which function of jsonstreamwriter would be used..

  18. Hannes Holst says:

    Hi there,

    many thanks for your blogpost. It saved me a lot of time.
    In my scenario, I was confronted with an Endpoint that accepts TLS1.1 and TLS1.2 only (it’s a payment service).
    The HttpWebRequest-Objects normally tries with SSL2 first and selects the next “higher” protocol if SSL2 is not accepted (SSL2 -> SSL3 -> TLS1.0 -> TLS1.1 -> TLS1.2). But, my Endpoint refused immediately the SSL2-attempt and closed the whole connection.

    To solve this problem I had to tell the HttpWebRequest-object which protocol to use.
    Two new DotNet-variables are necessary for this:
    ServicePointManager [System.Net.ServicePointManager.’System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089′]
    SecurityProtocol [System.Net.SecurityProtocolType.’System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089′]

    And added the following code to the function “DoWebRequest”:
    ServicePointManager.SecurityProtocol(SecurityProtocol.Tls12); // this is the new line
    NAVWebRequest := NAVWebRequest.NAVWebRequest;
    IF NOT NAVWebRequest.doRequest(HttpWebRequest,HttpWebException,HttpWebResponse) THEN

    Works fine 🙂

    Cheers,
    Hannes

    PS: and add the line “HttpWebRequest.ContentType(‘application/json’);” to the function CreateWebRequest

  19. massimo says:

    Hi can you explain me like to read a string JSON for using with XMLport, becouse I have not found the function :InsertFileDetails(TempPostingExchFiel.
    thanks in advance

  20. Hi Massimo.

    I use the JsonConvert library to convert between Json and Xml. Sometimes I use XmlPorts and sometimes I use DotNet Xml and Codeunit 6224.

  21. entwicklerdotnav says:

    Hi Gunnar,
    I’m new to JSON and NAV and very happy to find your blog. Thanks a lot.
    I Have a problem with function getJSon.
    This call
    JSon := StringBuilder.ToString;
    cuts the string, maximum length I get is 250. I tried with Text[1024] and also I built a GetJson( var String ->dotnet.string) function, always the same.
    Any Idea?
    Thanks in appreciation for your answer.
    Kind regards
    Andreas

    1. Hi Andreas.
      This is unknown to me. I believe that StringBuilder.ToString should always deliver the whole string.

  22. Mahesh U says:

    Hi Gunnar,

    Thanks for the post. it worked for me. But now i have to connect rest api with oauth 1.0(one leg) authentication. how to achieve that please make a blog on that it would be very helfpful for me.

    Thanks and Regards
    Mahesh U

  23. gwaindepyk says:

    Hi i am facing a challenge with the dll file, Error: Could not load type ‘Newtonsof.Json.JsonTextWriter.’Newtonsoft.Json,Version=4.5.0.0….
    I have downloaded the latest details as well as registered them, but I still get this error and I cant combile my codeunit on Nav 2016

    please help

    1. I suggest that you go into your Client Folder (C:\Program Files (x86)\Microsoft Dynamics NAV\100\RoleTailored Client), locate Newtonsoft.Json.dll and copy it into the Add-Ins folder. Use the version that is shipped with your NAV.

Leave a Reply

%d bloggers like this: