Thursday, September 29, 2022

Deserialize JSON string in D365FO using X++ code

Hi All,
Hope everyone is doing great.

Today we are here to learn one of the common requirement in every integration i.e. how to de-serialize JSON string in D365FO/AX7 using X++ code.

Below is the JSON which is showing the population count by country and our requirement is to show all this details in Infolog or insert into AX Table.

Solution :
1) Create contract class for both outer and inner node.
2) Use FormJsonSerializer::deserializeObject method.

Sample JSON : "data": [
        {
            "ID Nation""01000US",
            "Nation""United States",
            "ID Year"2020,
            "Year""2020",
            "Population"326569308,
            "Slug Nation""united-states"
        },
        {
            "ID Nation""01000US",
            "Nation""United States",
            "ID Year"2019,
            "Year""2019",
            "Population"324697795,
            "Slug Nation""united-states"
        }]

Step 1 : Create contract class 1 to hold all the values of data node. 
Note : DataMemberAttribute name should be matched with JSON key name i.e. data, ID Nation

[DataContract]
internal final class TestJSONContract
{

    String50 parmNationId, parmNation,parmYearId,parmYear,parmPopulation,parmSlugNation;

    [DataMemberAttribute('ID Nation')]
    public String50 parmNationId(String50 _parmNationId = parmNationId)
    {

        parmNationId = _parmNationId;

        return parmNationId;

    }

    [DataMemberAttribute('Nation')]

    public String50 parmNation(String50 _parmNation = parmNation)

    {

        parmNation = _parmNation;

        return parmNation;

    }

    [DataMemberAttribute('ID Year')]

    public String50 parmYearId(String50 _parmYearId = parmYearId)

    {

        parmYearId = _parmYearId;

        return parmYearId;

    }

    [DataMemberAttribute('Year')]

    public String50 parmYear(String50 _parmYear = parmYear)

    {

        parmYear = _parmYear;

        return parmYear;

    }

    [DataMemberAttribute('Population')]
    public String50 parmPopulation(String50 _parmPopulation = parmPopulation)
    {

        parmPopulation = _parmPopulation;

        return parmPopulation;
    }


    [DataMemberAttribute('Slug Nation')]
    public String50 parmSlugNation(String50 _parmSlugNation = parmSlugNation)
    {

        parmSlugNation = _parmSlugNation;

        return parmSlugNation;

    }

}

Step 2 : Create contract class for outer node.

In your case if there is more than one outer node then you need to create your class according to your JOSN. ex- if you have status and data node in your JSON but "status" is string type and "data" node contains multiple sub node then you need to create one more attribute in below class with string type and data with list type.

[DataContract]
internal final class TestJSONDataContract

{
    List parmData;
    [DataMemberAttribute('data'),DataCollectionAttribute(Types::class, classStr(TestJSONContract))]

    public List parmData(List _parmData = parmData)
    {
        parmData = _parmData;

        return parmData;
    }
}

Step 3: Create runnable class to call your API and get the result.
internal final class TestConsumeAPITest
{

    /// <summary>
    /// Class entry point. The system will call this method when a designated menu |
    /// is selected or when execution starts and this class is set as the startup class.
    /// </summary>
    /// <param name = "_args">The specified arguments.</param>

    public static void main(Args _args)
    {

        System.Net.HttpWebRequest      webRequest;
        System.Net.HttpWebResponse    webresponse;
        System.Exception                        ex;
        System.IO.Stream                        responseStream;
        System.IO.StreamReader             reader;
        str                                                 output;
        ListEnumerator                            listEnumerator;

        try
        {
            new InteropPermission(InteropKind::ClrInterop).assert();

            webRequest = System.Net.WebRequest::Create("##########"); //your API URL goes here.       

            webRequest.Method = "GET";
            webRequest.ContentType = "application/json";
            webresponse = webRequest.GetResponse();
            responseStream = webresponse.GetResponseStream();
            reader = new System.IO.StreamReader(responseStream);

            output = reader.ReadToEnd();

            TestJSONDataContract  TestJSONDataContract =                  FormJsonSerializer::deserializeObject(classNum(TestJSONDataContract),output);

            List listData = new List(Types::Class);

            listData             = TestJSONDataContract.parmData();
            listEnumerator  = listData.getEnumerator();

            while (listEnumerator.moveNext())
            {

                TestJSONContract jsonDataContract = listEnumerator.current();

                info(strFmt("Nation id %1 : %2 = %3",jsonDataCOntract.parmNationId(),              jsonDataContract.parmNation(), jsonDataContract.parmPopulation()));
            }

        }

        catch
        {
            ex = CLRInterop::getLastException().GetBaseException();
            error(ex.get_Message());

        }

    }

}


Step Final : Execute your runnable class to test the API and JSON format.







Post partial packing slip in D365FO

How to Post a Partial Packing Slip in D365FO and AX 2012 How to Post a Partial Packing Slip in D365FO and AX 2012 Understanding t...