AX / D365FO – Deserialize JSON string in D365FO using X++ 

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
{
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.

One response to “AX / D365FO – Deserialize JSON string in D365FO using X++ ”

  1. Rob Gik Avatar
    Rob Gik

    Still need InteropPermission these days?

    Like

Leave a comment