Skip to main content

Notifications

Announcements

No record found.

Community site session details

Community site session details

Session Id :
Finance | Project Operations, Human Resources, ...
Answered

How to display the response of a REST webservice in a readable way.

(0) ShareShare
ReportReport
Posted on by 50

Hello, 

I consume a webservice REST from a supplier to track the shipments. 

In AX I use this code : 

static void AccessingAPIv4(Args _args)
{
    str                             url;
    str                             method;
    str                             header;
    System.Net.HttpWebRequest       httpRequest;
    System.Net.HttpWebResponse      httpResponse;
    System.Net.WebHeaderCollection  headers;
    CLRObject                       clro;

    int batchSize = 1024;
    System.IO.Stream receiveStream;
    System.IO.StreamReader readStream;
    System.Text.Encoding encode;
    System.Char[] read;
    System.Text.StringBuilder sb;
    System.String readString;
    str contentEncoding;

    int countRead;

    ;

    url = "https://api.dachser.com/rest/v2/shipmenthistory?tracking-number=3616047827517440";
    method = "GET";

    try
    {
        clro         = System.Net.WebRequest::Create(url);
        httpRequest  = clro;

        headers = new System.Net.WebHeaderCollection();
        headers.Add("X-IBM-Client-Id", "77079f46c44fd809905968e00edc7eec");
        headers.Add("Accept-Language", "fr");

        httpRequest.set_Headers(headers);
        httpRequest.set_Method(method);
        httpRequest.set_ContentType("application/json");

        httpResponse = httpRequest.GetResponse();

        if (httpResponse)
        {
            receiveStream = httpResponse.GetResponseStream();
            contentEncoding = httpResponse.get_ContentEncoding();

            if (contentEncoding)
            {
                encode = System.Text.Encoding::GetEncoding(contentEncoding);
            }
            else
            {
                encode = new System.Text.UTF8Encoding();
            }

            readStream = new System.IO.StreamReader(receiveStream, encode);
            read = new System.Char[batchSize]();

            countRead = readStream.Read(read, 0, batchSize);

            sb = new System.Text.StringBuilder();
            while (countRead > 0)
            {
                readString = new System.String(read, 0, countRead);
                sb.Append(readString);
                countRead = readStream.Read(read, 0, batchSize);
            }

            readStream.Close();

            info(sb.ToString());
        }
    }
    catch(Exception::CLRError)
    {
        throw error(AifUtil::getClrErrorMessage());
    }

}

But the result in json is unreadable for a user : 

2625.2022_2D00_01_2D00_26_5F00_08_2D00_41_2D00_43.png

In XML : 

6710.2022_2D00_01_2D00_26_5F00_08_2D00_46_2D00_27.png

I would like to display a clear text. For example : 

ID : xxxxxxx

ShipmentDate : 2022-01-25

          Forwarder:

                    PartnerGLN : 4022128000003

                    Name : DACHSER SE Logistikzentrum Allgäu

          AddressInformation:

                    City: Memmingen

                    PostalCode : 87700

                    CountryCode : DE

          ShipmentWeight:

                    Weight : 811.59

                    Unit : kg

PortOfDeparture: CGC

PortOfDestination : MUC

Consignor:

          id:57335219

          partnerGLN : 5607427157528

          names : Sams c/o Taschenbier

          AddressInformation : 

                    Streets : Boulevard de Parc 12

                    City : Coupvray

                    postalCode: 77700

                    CountryCode : FR

.....

....

in XML on the supplier's API I get this information maybe it is clearer for you . 

{
    "shipments": [
        {
            "id": "A8653470034371833856",
            "shipmentDate": "2022-01-24",
            "forwarder": {
                "id": "6",
                "partnerGLN": "4022128000003",
                "names": [
                    "DACHSER SE Logistikzentrum Allgäu"
                ],
                "addressInformation": {
                    "city": "Memmingen",
                    "postalCode": "87700",
                    "countryCode": "DE"
                }
            },
            "shipmentWeight": {
                "weight": 811.59,
                "unit": "kg"
            },
            "portOfDeparture": "CGC",
            "portOfDestination": "MUC",
            "consignor": {
                "id": "84065035",
                "partnerGLN": "1774679107268",
                "names": [
                    "Daisy Duck"
                ],
                "addressInformation": {
                    "streets": [
                        "Boulevard de Parc 12"
                    ],
                    "city": "Coupvray",
                    "postalCode": "77700",
                    "countryCode": "FR"
                }
            },
            "consignee": {
                "id": "57335219",
                "partnerGLN": "5607427157528",
                "names": [
                    "Sams c/o Taschenbier"
                ],
                "addressInformation": {
                    "streets": [
                        "Bavariafilmpl. 7"
                    ],
                    "city": "Grünwald",
                    "postalCode": "82031",
                    "countryCode": "DE"
                }
            },
            "references": [
                {
                    "code": "003",
                    "value": "bmHTYBiz6r"
                },
                {
                    "code": "007",
                    "value": "8zW1V6Qulv"
                },
                {
                    "code": "HAW",
                    "value": "nYR45812933"
                }
            ],
            "status": [
                {
                    "statusSequence": 1,
                    "id": "12090048571",
                    "statusDate": "2022-01-24T04:31:00",
                    "eventSetter": {
                        "id": "6",
                        "partnerGLN": "4022128000003",
                        "names": [
                            "DACHSER SE Logistikzentrum Allgäu"
                        ],
                        "addressInformation": {
                            "city": "Memmingen",
                            "postalCode": "87700",
                            "countryCode": "DE"
                        }
                    },
                    "event": {
                        "code": "Z",
                        "extendedCode": "",
                        "description": "Livré conforme"
                    },
                    "signorOfTheProofOfDelivery": "POTTER"
                },
                {
                    "statusSequence": 2,
                    "id": "39703452818",
                    "statusDate": "2022-01-23T08:19:00",
                    "eventSetter": {
                        "id": "250",
                        "partnerGLN": "4046823000007",
                        "names": [
                            "DACHSER Denmark A/S Logistics Centre Copenhagen"
                        ],
                        "addressInformation": {
                            "city": "Hvidovre",
                            "postalCode": "2650",
                            "countryCode": "DK"
                        }
                    },
                    "event": {
                        "code": "A",
                        "extendedCode": "",
                        "description": "Expédié vers le terminal"
                    }
                },
                {
                    "statusSequence": 3,
                    "id": "57954173029",
                    "statusDate": "2022-01-21T19:29:00",
                    "eventSetter": {
                        "id": "60",
                        "partnerGLN": "5990034733003",
                        "names": [
                            "LIEGL & DACHSER KFT."
                        ],
                        "addressInformation": {
                            "city": "Pilisvörösvár",
                            "postalCode": "2085",
                            "countryCode": "HU"
                        }
                    },
                    "event": {
                        "code": "E",
                        "extendedCode": "",
                        "description": "Arrivé au terminal"
                    }
                }
            ]
        }
    ]
}

How to manage formatting?

Thanks a lot for your help. 

  • Verified answer
    Janos Kovacs Profile Picture
    130 on at
    RE: How to display the response of a REST webservice in a readable way.

    I will agree with what Martin wrote and gave you a great example of how to use C# libraby.

    I don't know if there is a class in Microsoft Dynamics AX 2009 called RetailCommonWebAPI. If there is, you can try to use RetailCommonWebAPI::getMapFromJsonString(jsonStr). Example of use:
    https://allaboutdynamic.com/2018/12/18/d365-ax7read-parse-json-javascript-object-notation/

    However, if you would like to write your own parsers, I am sending some interesting articles:

    1. http://axgrind.azurewebsites.net/2015/05/AX-2009-and-JSON-Parsing/
    2. https://community.dynamics.com/ax/f/microsoft-dynamics-ax-forum/139853/using-json-in-ax/325896 written by Ammar Salah
  • Martin Dráb Profile Picture
    233,025 Most Valuable Professional on at
    RE: How to display the response of a REST webservice in a readable way.

    No, you don't. The method serializes the whole JSON string to objects. You get an instance of Rootobject, which contains an array of Shipment objects, which contain references to Consignor objects, arrays of Reference objects and so on.

  • mimi51340 Profile Picture
    50 on at
    RE: How to display the response of a REST webservice in a readable way.

    Thanks do I need to create a method for every node ? for example, shipmentdate, shipmentweight, consignor... ?

  • Martin Dráb Profile Picture
    233,025 Most Valuable Professional on at
    RE: How to display the response of a REST webservice in a readable way.

    AX 2009 uses .NET Framework 3.5.

  • mimi51340 Profile Picture
    50 on at
    RE: How to display the response of a REST webservice in a readable way.

    which one am I supposed to use ?

    2022_2D00_01_2D00_27_5F00_15_2D00_20_2D00_43.png

    And in addition, do I need to create a method for every node ? for example, shipmentdate, shipmentweight, consignor... ?

    Thanks

  • Martin Dráb Profile Picture
    233,025 Most Valuable Professional on at
    RE: How to display the response of a REST webservice in a readable way.

    You need a (de)serializer - I suggested using Newtonsoft.Json.

    I would create a method inside the C# library to accepting a string and returning an instance of the Rootobject class. For example:

    using Newtownsoft.Json;
    
    namespace JSONLibrary
    {
    	public class Shipments
    	{
    		public static Rootobject Deserialize(string json)
    		{
    			return JsonConvert.DeserializeObject(json);
    		}
    	}
    }

    By the way, I would rename Rootobject to something descriptive.

    Then call this method from X . You'll pass in the JSON string and you'll get Rootobject.

    JSONLibrary.Rootobject rootObject;
    ...
    json = readStream.ReadToEnd();
    rootObject = JSONLibrary.Shipments::Deserialize(json);

    By the way, you need to declare variables just for those objects that you'll refer to in your code.

  • mimi51340 Profile Picture
    50 on at
    RE: How to display the response of a REST webservice in a readable way.

    Hello,

    So I created a library classes in Visual Studio like :

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace JSONLibrary
    {
    
        public class Rootobject
        {
            public Shipment[] shipments { get; set; }
        }
    
        public class Shipment
        {
            public Shipmentdate shipmentDate { get; set; }
            public Shipmentweight shipmentWeight { get; set; }
            public string forwarderConsignmentNumber { get; set; }
            public string portOfDeparture { get; set; }
            public string portOfDestination { get; set; }
            public Consignor consignor { get; set; }
            public Consignee consignee { get; set; }
            public Reference[] references { get; set; }
            public Status[] statuses { get; set; }
            public string[] ssccs { get; set; }
        }
    
        public class Shipmentdate
        {
            public string date { get; set; }
        }
    
        public class Shipmentweight
        {
            public string weight { get; set; }
            public string unit { get; set; }
        }
    
        public class Consignor
        {
            public Partnerinformation partnerInformation { get; set; }
        }
    
        public class Partnerinformation
        {
            public string partnerName { get; set; }
            public string partnerGLN { get; set; }
            public Addressinformation addressInformation { get; set; }
        }
    
        public class Addressinformation
        {
            public string street { get; set; }
            public string postalCode { get; set; }
            public string countryCode { get; set; }
            public string city { get; set; }
        }
    
        public class Consignee
        {
            public Partnerinformation1 partnerInformation { get; set; }
        }
    
        public class Partnerinformation1
        {
            public string partnerName { get; set; }
            public string partnerGLN { get; set; }
            public Addressinformation1 addressInformation { get; set; }
        }
    
        public class Addressinformation1
        {
            public string street { get; set; }
            public string city { get; set; }
            public string postalCode { get; set; }
            public string countryCode { get; set; }
        }
    
        public class Reference
        {
            public string code { get; set; }
            public string referenceNo { get; set; }
        }
    
        public class Status
        {
            public string statusSequence { get; set; }
            public string statusNumber { get; set; }
            public Statusdate statusDate { get; set; }
            public Eventsetter eventSetter { get; set; }
            public Event _event { get; set; }
        }
    
        public class Statusdate
        {
            public string date { get; set; }
            public string time { get; set; }
        }
    
        public class Eventsetter
        {
            public Partnerinformation2 partnerInformation { get; set; }
        }
    
        public class Partnerinformation2
        {
            public string partnerGLN { get; set; }
            public string partnerName { get; set; }
            public Addressinformation2 addressInformation { get; set; }
        }
    
        public class Addressinformation2
        {
            public string city { get; set; }
            public string postalCode { get; set; }
            public string countryCode { get; set; }
        }
    
        public class Event
        {
            public string code { get; set; }
            public string extendedCode { get; set; }
            public string description { get; set; }
        }
    
    }
    

    I added the library in AX as Reference. 

    I created a new class in AX. I think I need to declare all objects ? 

    2022_2D00_01_2D00_27_5F00_11_2D00_42_2D00_40.png

    And now how to exploit the result of the web service to send it in a table from this method ? 

    static void AccessingAPIv4(Args _args)
    {
        str                             url;
        str                             method;
        str                             header;
        System.Net.HttpWebRequest       httpRequest;
        System.Net.HttpWebResponse      httpResponse;
        System.Net.WebHeaderCollection  headers;
        CLRObject                       clro;
    
        int batchSize = 1024;
        System.IO.Stream receiveStream;
        System.IO.StreamReader readStream;
        System.Text.Encoding encode;
        System.Char[] read;
        System.Text.StringBuilder sb;
        System.String readString;
        str contentEncoding;
    
        int countRead;
    
        ;
    
        url = "https://api.dachser.com/rest/v2/shipmenthistory?tracking-number=3616047827517440";
        method = "GET";
    
        try
        {
            clro         = System.Net.WebRequest::Create(url);
            httpRequest  = clro;
    
            headers = new System.Net.WebHeaderCollection();
            headers.Add("X-IBM-Client-Id", "77079f46c44fd809905968e00edc7eec");
            headers.Add("Accept-Language", "fr");
    
            httpRequest.set_Headers(headers);
            httpRequest.set_Method(method);
            httpRequest.set_ContentType("application/json");
    
            httpResponse = httpRequest.GetResponse();
    
            if (httpResponse)
            {
                receiveStream = httpResponse.GetResponseStream();
                contentEncoding = httpResponse.get_ContentEncoding();
    
                if (contentEncoding)
                {
                    encode = System.Text.Encoding::GetEncoding(contentEncoding);
                }
                else
                {
                    encode = new System.Text.UTF8Encoding();
                }
    
                readStream = new System.IO.StreamReader(receiveStream, encode);
                read = new System.Char[batchSize]();
    
                countRead = readStream.Read(read, 0, batchSize);
    
                sb = new System.Text.StringBuilder();
                while (countRead > 0)
                {
                    readString = new System.String(read, 0, countRead);
                    sb.Append(readString);
                    countRead = readStream.Read(read, 0, batchSize);
                }
    
                readStream.Close();
    
                info(sb.ToString());
            }
        }
        catch(Exception::CLRError)
        {
            throw error(AifUtil::getClrErrorMessage());
        }
    
    }

    Thanks a lot

  • Martin Dráb Profile Picture
    233,025 Most Valuable Professional on at
    RE: How to display the response of a REST webservice in a readable way.

    As I said, this can be done with Edit > Paste Special > Paste JSON as Classes in Visual Studio. If you want more details, simply put these keywords to a web search engine. You'll find pages like this: How To Paste JSON As Classes Or XML As Classes in Visual Studio.

  • mimi51340 Profile Picture
    50 on at
    RE: How to display the response of a REST webservice in a readable way.

    How can I create a c# classes from JSON ? I do not understand sorry...

  • Martin Dráb Profile Picture
    233,025 Most Valuable Professional on at
    RE: How to display the response of a REST webservice in a readable way.

    If I was, I would create a C# class library. I would generate C# classes from JSON (with Edit > Paste Special > Paste JSON as Classes) and the used Newtonsoft.Json library to deserialize the JSON string to instance of these classes.

    Then I would add a reference to this C# libary and call it from X++ (via CLR Interop). Mapping properties of classes to table fields is then very easy.

    Of course, there are other JSON-related libraries as well. In the worst case, you can write your own JSON parser.

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

🌸 Community Spring Festival 2025 Challenge 🌸

WIN Power Platform Community Conference 2025 tickets!

Jonas ”Jones” Melgaard – Community Spotlight

We are honored to recognize Jonas "Jones" Melgaard as our April 2025…

Kudos to the March Top 10 Community Stars!

Thanks for all your good work in the Community!

Leaderboard

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 294,321 Super User 2025 Season 1

#2
Martin Dráb Profile Picture

Martin Dráb 233,025 Most Valuable Professional

#3
nmaenpaa Profile Picture

nmaenpaa 101,158 Moderator

Leaderboard

Product updates

Dynamics 365 release plans