D365FO JSON serialization and deserialization

Contract classes:
[DataContractAttribute('MainContract')]
class VKMainContract
{
    protected str                    status;
    protected VKAdditionalContact    additionalContract;
    protected List                    subList;

    
    [DataMemberAttribute("Status")]
    public str parmStatus(str _status = status)
    {
        status = _status;
        return status;
    }

    [DataMemberAttribute("AdditionalContract")]
    public VKAdditionalContact parmAdditionalContract(VKAdditionalContact _additionalContract = additionalContract)
    {
        additionalContract = _additionalContract;
        return additionalContract;
    }

    [DataMemberAttribute("ContractList"),
        DataCollectionAttribute(Types::Class, classStr(VKThirdContract))]
    public List parmSubList(List _subList = subList)
    {
        subList = _subList;
        return subList;
    }
}
[DataContractAttribute("AdditionalContact")]
class VKAdditionalContact
{
    protected str field;

    [DataMemberAttribute("SomeAdditionalField")]
    public str parmSomeAdditionalField(str _field = field)
    {
        field = _field;
        return field;
    }

}
[DataContractAttribute('ThirdContract')]
class VKThirdContract
{
    protected str    field1;
    protected str    field2;

    [DataMemberAttribute("SomeField1")]
    public str parmSomeField1(str _field = field1)
    {
        field1 = _field;
        return field1;
    }

    [DataMemberAttribute("SomeField2")]
    public str parmSomeField2(str _field = field2)
    {
        field2 = _field;
        return field2;
    }

}
JSON example:
[
   {
      "AdditionalContract":{
         "SomeAdditionalField":"test1"
      },
      "ContractList":[
         {
            "SomeField1":"field1",
            "SomeField2":"field2"
         },
         {
            "SomeField1":"field1",
            "SomeField2":"field2"
         }
      ],
      "Status":"status1"
   },
   {
      "AdditionalContract":{
         "SomeAdditionalField":"test2"
      },
      "ContractList":[
         {
            "SomeField1":"field1",
            "SomeField2":"field2"
         },
         {
            "SomeField1":"field1",
            "SomeField2":"field2"
         }
      ],
      "Status":"status2"
   }
]
Runnable class to serialize contracts to JSON and then deserialize JSON back to same contracts:
class VKTest
{
    public static void main(Args _args)
    {
        VKAdditionalContact    additionalContact    = new VKAdditionalContact();
        VKMainContract        mainContract        = new VKMainContract();
        VKThirdContract        thirdContract        = new VKThirdContract();
        List                itemMainList        = new List(Types::Class);
        List                itemThirdList        = new List(Types::Class);

        thirdContract.parmSomeField1('field1');
        thirdContract.parmSomeField2('field2');
        itemThirdList.addEnd(thirdContract);
        itemThirdList.addEnd(thirdContract);

        additionalContact.parmSomeAdditionalField('test1');
        
        mainContract.parmAdditionalContract(additionalContact);
        mainContract.parmStatus('status1');
        mainContract.parmSubList(itemThirdList);

        itemMainList.addEnd(mainContract);

        mainContract        = new VKMainContract();
        additionalContact    = new VKAdditionalContact();
        additionalContact.parmSomeAdditionalField('test2');
        mainContract.parmStatus('status2');
        mainContract.parmAdditionalContract(additionalContact);
        mainContract.parmSubList(itemThirdList);
        itemMainList.addEnd(mainContract);

        // case 1: json starts from array []
        str json = FormJsonSerializer::serializeClass(itemMainList);
        // case 2: json starts from object {}
        //str json = FormJsonSerializer::serializeClass(mainContract);
        info(json);

        itemMainList        = new List(Types::Class);
        itemThirdList        = new List(Types::Class);
        mainContract        = new VKMainContract();
        additionalContact    = new VKAdditionalContact();
        thirdContract        = new VKThirdContract();
        ListEnumerator     leSub;

        // case 1
        itemMainList = FormJsonSerializer::deserializeCollection(classnum(List), json, Types::Class, identifierStr('VKMainContract'));
        ListEnumerator     le = itemMainList.getEnumerator();
        while (le.moveNext())
        {
            mainContract        = le.current();
            additionalContact    = mainContract.parmAdditionalContract();
            itemThirdList        = mainContract.parmSubList();
            leSub                = itemThirdList.getEnumerator();
            while (leSub.moveNext())
            {
                thirdContract = leSub.current();
            }
        }

        // case 2
        /*mainContract = FormJsonSerializer::deserializeObject(classNum(VKMainContract), json);
        additionalContact    = mainContract.parmAdditionalContract();
        itemThirdList        = mainContract.parmSubList();
        leSub                = itemThirdList.getEnumerator();
        while (leSub.moveNext())
        {
            thirdContract = leSub.current();
        }*/

        info("done");
    }

}
JSON does not have to completely match the contract. In that case only matching properties will be filled in. That is valid only for simple types like string and integer, for objects and arrays at least empty contract class and parm method should be in place. Otherwise you might get following error: " the type of object cannot be set."
    json = '{"SomeField1":"field1","SomeAdditionalField":"field2"}';
    thirdContract = FormJsonSerializer::deserializeObject(classNum(VKThirdContract), json);
In case of simple JSON structure Map can be used to get values
    json = '{"SomeField1":"field1","SomeAdditionalField":"field2"}';
    Map            responseMap = RetailCommonWebAPI::getMapFromJsonString(json);
    container    con            = responseMap.lookup('SomeField1');
    str            value        = conPeek(con, 1);
D365 F&SCM date format: 2024-05-27T00:00:00Z
FormJsonSerializer.writeDateTimeValue

 

Search

About

DaxOnline.org is free platform that allows you to quickly store and reuse snippets, notes, articles related to Dynamics AX.

Authors are allowed to set their own AdSense units and "buy me a coffee" link.
Join us.

Blog Tags