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.
1) Create contract class for both outer and inner node.
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.