Skip to main content
Post a question

Notifications

Announcements

No record found.

Community site session details

Community site session details

Session Id : 5tWW4YxUeaGt8OGjO+/X4W
Finance | Project Operations, Human Resources, ...
Unanswered

Serialize Json string to send API request

Like (5) ShareShare
ReportReport
Posted on 29 Jan 2025 22:38:49 by 323
Hi,
 
I am trying to create JSON request body to send API request from D365FO. 
Below is the code I have tried to write by creating a container .Not sure if I can do it through container.
In some places I see that it needs a contract class to serialize as well as deserialize the json request and response.
 
Please help me create a contract class for serializing all the values into json string to form the request body.
 
            str order_id = projInvoiceJour.proposalid;
            str order_amount = num2Str(projInvoiceJour.invoiceamount,0,0,0,0);
            str order_currency = projInvoiceJour.currencyid;
            str order_expiry_time = date2Str(projInvoiceJour.duedate, 321,DateDay::Digits2,DateSeparator::Hyphen,DateMonth::Digits2, DateSeparator::Hyphen,DateYear::Digits4);
            str customerId = projInvoiceJour.InvoiceAccount;
            str customerPhone = dirPartyContactInfoView.Locator;
            str terminalId = parameters.CFTerminalID;
            str terminalPhone = parameters.CFTerminalPhone;
            str invoiceId = projInvoiceJour.projinvoiceid;
            str invoiceDate = date2Str(projInvoiceJour.invoicedate, 321,DateDay::Digits2,DateSeparator::Hyphen,DateMonth::Digits2, DateSeparator::Hyphen,DateYear::Digits4);
            str gstin = taxReg.registrationNumber;
            str gst = num2Str(abs(taxTransCGST.taxAmountCur) + abs(taxTransSGST.taxAmountCur),0,0,0,0);
            str cgst = num2Str(abs(taxTransCGST.taxAmountCur),0,0,0,0);
            str sgst = num2Str(abs(taxTransSGST.taxAmountCur),0,0,0,0);
            str invoice_name = projInvoiceJour.DeliveryName;


            jsonContainer = [
    ['order_id', order_id],
   ['order_amount', order_amount],
   ['order_currency', order_currency],
   ['customer_details', [
        ['customer_id', customerId],
   ['customer_phone', customerPhone]
            ]],
    ['terminal', [
        ['cf_terminal_id', terminalId],
   ['terminal_type', 'SPOS'],
   ['terminal_phone_no', terminalPhone]
            ]],
    ['order_expiry_time', order_expiry_time],
   ['order_tags', [
        ['invoice_number', invoiceId],
   ['invoice_date', invoiceDate],
   ['gstin', gstin],
      ['gst', gst],
        ['cgst', cgst],
        ['sgst', sgst],
       ['invoice_name', invoice_name]

            ]]
];

str  orderJson = FormJsonSerializer::serializeClass(ContractClass);

 encoding = System.Text.Encoding::get_UTF8();
 stringContent = new System.Net.Http.StringContent(orderJson, encoding, "application/json");

 headers = httpClient.DefaultRequestHeaders;

 headers.Add('x-api-version', apiVersion);
 headers.Add('x-client-id', clientId);
 headers.Add('x-client-secret', clientSecret);
 headers.Add('x-idempotency-key', idempotencyKey);
 headers.Add('x-request-id', requestId);
 
 
Do I have to create parm methods for all the fields ? How will the different nodes be defined in contract class (By nodes I mean - data, customer details,terminal, order_tags) ?
 
Please help.
 
Thanks,
Priya
  • Martin Dráb Profile Picture
    231,647 Most Valuable Professional on 04 Feb 2025 at 05:32:39
    Serialize Json string to send API request
    Could you read my response once more, please? I do understand that the sequence of elements isn't what you expected, but that in itself doesn't mean that there is a problem. 
     
    Regarding "there is some issue with the contract classes returning null values", please give us a more detailed description of this problem.
  • PriyaDutta Profile Picture
    323 on 04 Feb 2025 at 00:22:22
    Serialize Json string to send API request
    Hi,
     
    Looks like there is some issue with the contract classes returning null values in json even when in debugging I can see the parm methods getting the values .
      dataContract.parmOrderID(projInvoiceJour.proposalid);
               
      dataContract.parmOrderAmt( num2Str(projInvoiceJour.invoiceamount,0,0,0,0));
               
      dataContract.parmOrderCurrency(projInvoiceJour.currencyid);
                
      //custDetailsContract.init('cust123','2564');
    
      custDetailsContract.parmCustID('cust123');
      custDetailsContract.parmCustPhone('2564');
    
    
      //itemdataList.addEnd(dataContract);
    
      terminalDetContract.parmCfTerminalID(parameters.CFTerminalID);
      terminalDetContract.parmCfTerminalPhone( parameters.CFTerminalPhone);
      terminalDetContract.parmCfTerminalType( parameters.CFTerminalType);
              
      HS_QRCodeGenerationOrderTagsContract orderTagsContract = new HS_QRCodeGenerationOrderTagsContract();
      orderTagsContract.parmInvNum( projInvoiceJour.projinvoiceid);
      orderTagsContract.parmInvDate(date2Str(projInvoiceJour.invoicedate, 321,DateDay::Digits2,DateSeparator::Hyphen,DateMonth::Digits2, DateSeparator::Hyphen,DateYear::Digits4));
      orderTagsContract.parmGSTIN(taxReg.registrationNumber);
      orderTagsContract.parmGST(num2Str(abs(taxTransCGST.taxAmountCur) + abs(taxTransSGST.taxAmountCur),0,0,0,0));
      orderTagsContract.parmCGST( num2Str(abs(taxTransCGST.taxAmountCur),0,0,0,0));
      orderTagsContract.parmSGST(num2Str(abs(taxTransSGST.taxAmountCur),0,0,0,0));
      orderTagsContract.parmInvName(projInvoiceJour.DeliveryName);
      
    
      HS_QRCodeGenerationMasterContract mainContract        = new HS_QRCodeGenerationMasterContract();
      dataContract.parmCustDetailsContract(custDetailsContract);
      mainContract.parmDataContract(dataContract);
      mainContract.parmTerminalDetaContract(terminalDetContract);
      
      mainContract.parmOrderExpiryTime(date2Str(projInvoiceJour.duedate, 321,DateDay::Digits2,DateSeparator::Hyphen,DateMonth::Digits2, DateSeparator::Hyphen,DateYear::Digits4));
     
      mainContract.parmOrderTags(orderTagsContract);
    
      orderJson =  FormJsonSerializer::serializeClass(mainContract);
    Am i correctly calling the objects and in sequence . Am i missing to insert some values in the contract ?
  • PriyaDutta Profile Picture
    323 on 03 Feb 2025 at 17:26:28
    Serialize Json string to send API request
    Hi Martin, 
    The problem is the json string I need to send for API request is not coming as expected. 
    Expected json request body looks like :
     
    whereas my json looks like arranged alphabetically somehow.

     
    Order id , order amount, order currency, then customer details. And end with orderTags.
     
     
  • Martin Dráb Profile Picture
    231,647 Most Valuable Professional on 03 Feb 2025 at 13:44:24
    Serialize Json string to send API request
    What is the problem? It produces JSON with the correct properties and data. If it merely doesn't look like you expected, then there is no real problem to address.
     
    If the software processing the file doesn't work with this order of properties, isn't it actually a bug there?
     
    If you really have no other choice than changing the order of properties, I don't think you can do it at this place. Newtonsoft.Json serialization has JsonPropertyAttribute.Order property for this purpose, but I don't see how you could use it from X++. (I may be missing something, though.) A viable solution may be transforming the response in Azure API Management or something like that.
  • PriyaDutta Profile Picture
    323 on 03 Feb 2025 at 09:39:27
    Serialize Json string to send API request
    Hi Layan,
     
    Iam able to create the json string through contract classes. But the sequence of the string is coming alphabetically no matter how I call the parm methods.
    Can u please see my code below :
      HS_QRCodeGenerationCustDetailsContract custDetailsContract = new HS_QRCodeGenerationCustDetailsContract();
      HS_QRCodeGenerationTerminalDetContract terminalDetContract = new HS_QRCodeGenerationTerminalDetContract();
      HS_QRCodeGenerationDataContract dataContract = new HS_QRCodeGenerationDataContract();
      
      List                itemdataList        = new List(Types::Class);
      List                itemContractList        = new List(Types::Class);
      List                itemtermList        = new List(Types::Class);
      List                itemOrderList        = new List(Types::Class);
             
    
      dataContract.parmOrderID(projInvoiceJour.proposalid);
     
      dataContract.parmOrderAmt( num2Str(projInvoiceJour.invoiceamount,0,0,0,0));
     
      dataContract.parmOrderCurrency(projInvoiceJour.currencyid);
      
    
      
      custDetailsContract.parmCustID('cust123');
      custDetailsContract.parmCustPhone('2564');
     // itemContractList.addEnd(custDetailsContract);
    
      dataContract.parmCustDetailsContract(custDetailsContract);
      itemdataList.addEnd(dataContract);
    
      terminalDetContract.parmCfTerminalID(parameters.CFTerminalID);
      terminalDetContract.parmCfTerminalPhone( parameters.CFTerminalPhone);
      terminalDetContract.parmCfTerminalType( parameters.CFTerminalType);
      itemtermList.addEnd(terminalDetContract);
    
     // mainContract.parmOrderExpiryTime(date2Str(projInvoiceJour.duedate, 321,DateDay::Digits2,DateSeparator::Hyphen,DateMonth::Digits2, DateSeparator::Hyphen,DateYear::Digits4));
     
      HS_QRCodeGenerationOrderTagsContract orderTagsContract = new HS_QRCodeGenerationOrderTagsContract();
      orderTagsContract.parmInvNum( projInvoiceJour.projinvoiceid);
      orderTagsContract.parmInvDate(date2Str(projInvoiceJour.invoicedate, 321,DateDay::Digits2,DateSeparator::Hyphen,DateMonth::Digits2, DateSeparator::Hyphen,DateYear::Digits4));
      orderTagsContract.parmGSTIN(taxReg.registrationNumber);
      orderTagsContract.parmGST(num2Str(abs(taxTransCGST.taxAmountCur) + abs(taxTransSGST.taxAmountCur),0,0,0,0));
      orderTagsContract.parmCGST( num2Str(abs(taxTransCGST.taxAmountCur),0,0,0,0));
      orderTagsContract.parmSGST(num2Str(abs(taxTransSGST.taxAmountCur),0,0,0,0));
      orderTagsContract.parmInvName(projInvoiceJour.DeliveryName);
      itemOrderList.addEnd(orderTagsContract);
    
      HS_QRCodeGenerationMasterContract mainContract        = new HS_QRCodeGenerationMasterContract();
     
      mainContract.parmDataContract(dataContract);
      
      mainContract.parmTerminalDetaContract(terminalDetContract);
    
      mainContract.parmOrderExpiryTime(date2Str(projInvoiceJour.duedate, 321,DateDay::Digits2,DateSeparator::Hyphen,DateMonth::Digits2, DateSeparator::Hyphen,DateYear::Digits4));
    
      mainContract.parmOrderTags(orderTagsContract);
      itemMainList.addEnd(mainContract);
     // mainContract.
    
          // Serialize the container into JSON
       //   FormJsonSerializer jsonSerializer = new FormJsonSerializer();
      orderJson =  FormJsonSerializer::serializeClass(itemMainList);
      Info(strfmt("string: %1",orderJson));
    JSON EXPECTED
    data '{
      "order_id": "INV-2024-144066",
      "order_amount": 193284,
      "order_currency": "INR",
      "customer_details": {
        "customer_id": "Cust-015628",
        "customer_phone": "9999999999"
      },
      "terminal": {
        "cf_terminal_id": 21732,
        "terminal_type": "SPOS",
        "terminal_phone_no": "8554956545"
      },
      "order_expiry_time": "2025-01-07T10:20:12+05:30",
      "order_tags": {
        "invoice_number": "BDO2425GUR003622",
        "invoice_date": "2024-12-12T00:00:00+05:30",
        "gstin": "06AANFB3386M1ZY",
        "gst": "29484.00",
        "cgst": "14742.00",
        "sgst": "14742.00",
        "invoice_name": "Unit 28 & 29, Level 18, The executive Center,"
      }
    }'
    
    JSON GENERATED:
     [{"Data":{"CustomerDetails":{},
    "order_amount":"1883",
    "order_currency":"USD",
    "order_id":"INV-2022-00174"},
    "order_expiry_time":"2022-09-01",
    "order_tags":{},
    "terminal":{}
    
    }}

    ​​​​​​​
    Thanks.
  • Layan Jwei Profile Picture
    7,717 Super User 2025 Season 1 on 02 Feb 2025 at 19:36:53
    Serialize Json string to send API request
    I'm glad it helped Priya. Thanks for coming back to us and verifying the answer.
  • PriyaDutta Profile Picture
    323 on 02 Feb 2025 at 17:08:26
    Serialize Json string to send API request
    Hi Layan,
     
    Yes Thank you very much . I have created contract classes using your advise.
     
     
  • Layan Jwei Profile Picture
    7,717 Super User 2025 Season 1 on 30 Jan 2025 at 19:19:11
    Serialize Json string to send API request
    Hi,
     
    Is your question answered? If yes then please verify the answer if it helped
  • Verified answer
    Layan Jwei Profile Picture
    7,717 Super User 2025 Season 1 on 29 Jan 2025 at 23:18:01
    Serialize Json string to send API request
    Hi,

    yes you need a contract class with parm methods, the way you build the contract class depends on how the json looks like.

    For example, if the json is like this:
        {
            "dataArea":"USMF",
            "accountNumber": "C000001",
            "currency": "GBP",
            "salesLines":   
            [
                {
                    "itemId":"item1",
                    "itemName": "item1name"
                },
                {
                    "itemId":"item2",
                    "itemName": "item2name"
                }
            ]
        }        

    then u need two contract classes like this:
    [DataContractAttribute]
    class SalesOrderReqContract
    {
        DataAreaId                          dataArea;   
        CustAccount                         accountNum;  
        CustCurrencyCode                    currency;  
        List                                salesOrderLines; 
    
    
        [DataMemberAttribute('dataAreaId')]
        public DataAreaId parmDataArea(DataAreaId _dataArea = dataArea)
        {
            dataArea = _dataArea;
            return dataArea;
        }
    
    
        [DataMemberAttribute('accountNumber')]
        public CustAccount parmAccountNum(CustAccount _accountNum = accountNum)
        {
            accountNum = _accountNum;
            return accountNum;
        }
    
    
        [DataMemberAttribute('currency')]
        public CustCurrencyCode parmCurrency(CustCurrencyCode _currency = currency)
        {
            currency = _currency;
            return currency;
        }
    
    
        [DataMemberAttribute('salesLines'),
        AifCollectionTypeAttribute('_salesOrderLines',Types::Class,classStr(SalesLineReqContract)),
        AifCollectionTypeAttribute('return',Types::Class,classStr(SalesLineReqContract))]
        public List parmSalesLines(List _salesOrderLines = salesOrderLines)
        {
            salesOrderLines = _salesOrderLines;
            return salesOrderLines;
        }
    }
    [DataContractAttribute]
    class SalesLineLineReqContract
    {
        ItemIdSmall             itemId;     
        ItemFreeTxt             itemName; 
    
    
        [DataMemberAttribute('itemId')]
        public ItemIdSmall parmItemId(ItemIdSmall _itemId = itemId)
        {
            itemId = _itemId;
            return itemId;
        }
    
        [DataMemberAttribute('itemName')]
        public ItemFreeTxt parmItemName(ItemFreeTxt _itemName = itemName)
        {
            itemName = _itemName;
            return itemName;
        }
    
    }


    so in your case you will need to fill all fields for the contract class, like this

    contract.parmAccoountNumber('000001');


    i didn't understand the container part, i hope i was able to help, if u need more info then please explain further.


    Thanks,
    Layan Jweihan
    Please mark this answer as "Verified" if it solved your issue. In order to help others who will face a similar issue in the future.


     

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

Daivat Vartak – Community Spotlight

We are honored to recognize Daivat Vartak as our March 2025 Community…

Announcing Our 2025 Season 1 Super Users!

A new season of Super Users has arrived, and we are so grateful for the daily…

Kudos to the February 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... 292,765 Super User 2025 Season 1

#2
Martin Dráb Profile Picture

Martin Dráb 231,647 Most Valuable Professional

#3
nmaenpaa Profile Picture

nmaenpaa 101,156 Moderator

Leaderboard

Product updates

Dynamics 365 release plans
Loading started