web
You’re offline. This is a read only version of the page.
close
Skip to main content

Notifications

Announcements

No record found.

Community site session details

Community site session details

Session Id :
Dynamics 365 Community / Forums / Finance forum / Sending a JSON List to...
Finance forum

Sending a JSON List to custom service

(0) ShareShare
ReportReport
Posted on by 250

Hello All,

I have a JSON list am trying to send to a custom service.

[
{
"EmployeeId":"ERS/CONS/67898",
"Gross":30567.90,
"NetPay":7890.89,
"EmployeePension":578564,
"EmployerPension":898789,
"PAYE":68798
}
,
{
"EmployeeId":"ERS/CONS/9087",
"Gross":30567.90,
"NetPay":7890.89,
"EmployeePension":578564,
"EmployerPension":898789,
"PAYE":68798
}
,
{
"EmployeeId":"ERS/CONS/6745",
"Gross":30567.90,
"NetPay":7890.89,
"EmployeePension":578564,
"EmployerPension":898789,
"PAYE":68798
}
,
{
"EmployeeId":"ERS/CONS/2345",
"Gross":30567.90,
"NetPay":7890.89,
"EmployeePension":578564,
"EmployerPension":898789,
"PAYE":68798
}
]

The code for the custom service is as follows;

[
DataCollectionAttribute(Types::Class, classStr(ERSPayrollRecordContract)),
]
public str createRecords(List _records)
{
ERSPayrollRecordContract payrollRecord;
ListEnumerator listEnum = _records.getEnumerator();
str txt="";
while(listEnum.moveNext())
{
payrollRecord = listEnum.current();
txt +=strFmt("%1, ", payrollRecord.EmployeeId());
}
return txt;
}

but i get this error in my API tester

{
"Message": "An exception occured when deserializing a parameters - Exception occured when parsing the request content - Error reading JObject from JsonReader. Current JsonReader item is not an object: StartArray. Path '', line 1, position 1.",
"ExceptionType": "XppServicesDeserializationException",
"ActivityId": "d3e970ed-9630-0003-20fd-e9d33096d401"
}
Please what am i doing wrong
I have the same question (0)
  • Martin Dráb Profile Picture
    237,801 Most Valuable Professional on at

    You should sent a JSON object with a property called _records (because that's how you've named the parameter) and the array as the value of this property.

  • Matthew Ireti Profile Picture
    250 on at

    Thanks Martins
    These are the modifications to the JSON String...
    {
    "record":
    [
    {
    "EmployeeId": "ERS/CONS/67898",
    "Gross": 30567.90,
    "NetPay": 7890.89,
    "EmployeePension": 578564,
    "EmployerPension": 898789,
    "PAYE": 68798
    },
    {
    "EmployeeId": "ERS/CONS/9087",
    "Gross": 30567.90,
    "NetPay": 7890.89,
    "EmployeePension": 578564,
    "EmployerPension": 898789,
    "PAYE": 68798
    }
    ]
    }
    and the service action method is
    [DataCollectionAttribute(Types::Class, classStr(ERSPayrollRecordContract))]
    public str createRecords(List record)
    {
    ERSPayrollRecordContract payrollRecord;
    ListEnumerator listEnum = record.getEnumerator();
    str txt="";
    while(listEnum.moveNext())
    {
    payrollRecord = listEnum.current();
    txt +=strFmt("%1, ", payrollRecord.EmployeeId());
    }
    return txt;
    }

    But I now get this error
    {
    "Message": "An exception occured when deserializing a parameters - Exception occurred when parsing and deserializing parameter 'record' - 'Error while deserializing contract class'",
    "ExceptionType": "XppServicesDeserializationException",
    "ActivityId": "d3e970ed-9630-0006-4e99-ead33096d401"
    }


    The dataContract Class is given below with all DataMemberAttributes validated. What am i dong wrong?

    [DataContractAttribute]
    public class ERSPayrollRecordContract
    {
    str _employeeId;
    real gross,paye,netPay,emplPension,employerPension;

    [DataMemberAttribute("EmployeeId")]
    public str EmployeeId(str _data = _employeeId)
    {
    _employeeId = _data;
    return _employeeId;
    }

    [DataMemberAttribute("Gross")]
    public real Gross(real _data = gross)
    {
    gross = _data;
    return gross;
    }

    [DataMemberAttribute("PAYE")]
    public real Paye(real _data = paye)
    {
    paye = _data;
    return paye;
    }

    [DataMemberAttribute("NetPay")]
    public real NetPay(real _data = netPay)
    {
    netPay = _data;
    return netPay;
    }

    [DataMemberAttribute("EmployeePension")]
    public real EmployeePension(real _data = emplPension)
    {
    emplPension = _data;
    return emplPension;
    }

    [DataMemberAttribute("EmployerPension")]
    public real EmployerPension(real _data = employerPension)
    {
    employerPension = _data;
    return employerPension;
    }

    }

  • Verified answer
    Martin Dráb Profile Picture
    237,801 Most Valuable Professional on at

    You also must use AifCollectionTypeAttribute for the parameter name (you can remove DataCollectionAttribute, which is used in data contract classes). Like this:

    [AifCollectionType('record', Types::Class, classStr(ERSPayrollRecordContract))]
    public str createRecords(List record)

    By the way, please use the </> button in the rich formatting view to paste source code, as I've done above.

  • MohitParkash Profile Picture
    35 on at

    Dear Martin,

    In AX i have created below code , but still getting internal server error. 

    [AifCollectionType('record', Types::Class, classStr(XMTrvReqListContract))]
        public List TrvReq_list(List record)
        {
            ListEnumerator                  enumerator = record.getEnumerator();
            List                             resultSet = new List(Types::String);
            XMTrvReqListContract             xMTrvReqListContract;
            str                              Company,Emplcode;
            TrvRequisitionTable              reqTable;
    
            while (enumerator.moveNext())
            {
    
                Company = xMTrvReqListContract.ParamCompanyCode();
                Emplcode = xMTrvReqListContract.ParamEmplCode();
                try
                {
                    changecompany(Company)
                    {
                        while select reqTable where reqTable.CreatingWorker == HcmWorker::findByPersonnelNumber(Emplcode).RecId
                        resultSet.addEnd(strFmt("%1,%2,%3",reqTable.RequisitionNumber,reqTable.TravelPurpose,reqTable.ApprovalStatus));
                    }
                }
                catch (Exception::CLRError)
                {
                    resultSet.addEnd(strfmt('%1',AifUtil::getClrErrorMessage()));
                }
                catch (Exception::Error)
                {
                    resultSet.addEnd(strfmt("Exception::Error caught"));
                }
            }
            return resultSet;
        }


    In Console application 

    namespace OAuthXppConsoleApplication
    {
        class Program
        {
            static void Main(string[] args)
            {
                XMTrvReqListContract XMTrvReqListContract = new XMTrvReqListContract();
    
                XMTrvReqListContract.Company = "USMF"; //This is MOST IMPORTANT 
                //XMTrvReqListContract.Emplcode = "000020";
                string json = JsonConvert.SerializeObject(XMTrvReqListContract);
    
    
                // Prepare HTTP client, including authentication
                HttpClient client = new HttpClient();
                client.BaseAddress = new Uri(ClientConfiguration.Default.UriString);
                client.DefaultRequestHeaders.Add(OAuthHelper.OAuthHeader, OAuthHelper.GetAuthenticationHeader());
    
               
                // Create a request
                HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post,
                                                                    "api/services/XMMobileServiceGroup/XMMobileService/TrvReq_List");
                request.Content = new StringContent(JsonConvert.SerializeObject(XMTrvReqListContract),
                                                    Encoding.UTF8,
                                                    "application/json");
    
                // Run the service
                var result = client.SendAsync(request).Result;
    
                // Display result to console
                if (result.IsSuccessStatusCode)
                {
                    Console.WriteLine(result.Content.ReadAsStringAsync().Result);
                }
                else
                {
                    Console.WriteLine(result.StatusCode);
                }
    
                Console.ReadLine();
            }
    
        }
        public class XMTrvReqListContract
    
        {
            public string Company { get; set; }
            public string Emplcode { get; set; }
    
    
        }
    }


  • Martin Dráb Profile Picture
    237,801 Most Valuable Professional on at

    You're sending wrong data. The operation an object with a 'record' property containing an array of XMTrvReqListContract objects, while your code provides a single XMTrvReqListContract object directly.

    By the way, you also don't have AifCollectionType for the return value and you should check whether your exception handling code is called at all (it won't be if it's inside a database transaction).

  • MohitParkash Profile Picture
    35 on at

    Dear Martin,

    Thanks i have made below changes in X++ code , but in AX getting error

    [AifCollectionType('record', Types::Class, classStr(XMTrvReqListContract))]
    public str TrvReq_list(list record)
    {
    ListEnumerator lEnum;
    List resultSet = new list (Types::Class);
    List list = new list (Types::Class);
    str Company,Emplcode,jsread;
    TrvRequisitionTable reqTable;
    XMTrvReqListContract xMTrvReqListContract = new XMTrvReqListContract();
    XMTrvReqListContract recordscontract = new XMTrvReqListContract();
    XMTrvReqReturnJson xMTrvReqReturnJson = new XMTrvReqReturnJson();

    try
    {
    //List records = FormJsonSerializer::deserializeValue(Types::String, record);
    //List records = FormJsonSerializer::deserializeCollection(classNum(List), jsonStr, Types::Class, classStr(XMTrvReqListContract));
    lEnum = record.getEnumerator();
    while (lEnum.MoveNext())
    {
    recordscontract = lEnum.current();
    Company = recordscontract.ParamCompanyCode();
    Emplcode = recordscontract.ParamEmplCode();

    changecompany(Company)
    {
    while select reqTable where reqTable.CreatingWorker == HcmWorker::findByPersonnelNumber(Emplcode).RecId
    {
    xMTrvReqReturnJson.ParamReqNum(reqTable.RequisitionNumber);
    xMTrvReqReturnJson.ParamTrvPurpose(reqTable.TravelPurpose);
    xMTrvReqReturnJson.ParamReqStatus(enum2Str(reqTable.ApprovalStatus));
    resultSet.addEnd(xMTrvReqReturnJson);
    }
    }
    }

    }
    catch (Exception::CLRError)
    {
    jsread = resultSet.addEnd(strfmt('%1',AifUtil::getClrErrorMessage()));
    }
    catch (Exception::Error)
    {
    jsread = resultSet.addEnd(strfmt("Exception::Error caught"));
    }
    jsread = FormJsonSerializer::serializeClass(resultSet);
    return jsread;

    Error in AX

    ExceptionText Newtonsoft.Json.JsonReaderException: Error reading JObject from JsonReader. Current JsonReader item is not an object: StartArray. Path '', line 1, position 1. at Newtonsoft.Json.Linq.JObject.Load(JsonReader reader, JsonLoadSettings settings) at Newtonsoft.Json.Linq.JObject.Parse(String json, JsonLoadSettings settings) at Microsoft.Dynamics.Platform.Integration.Services.Xpp.Serialization.ParameterDeserializer.DeserializeRequest(HttpRequestMessage request, OperationMetadata operationMetadata)
    infoMessage Exception occured when parsing the request content - Error reading JObject from JsonReader. Current JsonReader item is not an object: StartArray. Path '', line 1, position 1.

    JSON in Postman 

    ["record":
    {"Company":"USMF","Emplcode":"000020"}
    ]

  • Martin Dráb Profile Picture
    237,801 Most Valuable Professional on at

    Your code is very difficult to read, therefore let me fix if for you before we can look at it. I've added indentation, removed unused variables and moved variable declarations closer to where the variables are used:

    [AifCollectionType('record', Types::Class, classStr(XMTrvReqListContract))]
    public str TrvReq_list(List record)
    {
        List resultSet = new List(Types::Class);
        str jsread;
    
        try
        {
            ListEnumerator lEnum = record.getEnumerator();
            while (lEnum.MoveNext())
            {
                XMTrvReqListContract recordsContract = lEnum.current();
                str company = recordsContract.ParamCompanyCode();
                str emplCode = recordsContract.ParamEmplCode();
                
                changeCompany(Company)
                {
                    TrvRequisitionTable reqTable;
                    while select reqTable
                        where reqTable.CreatingWorker == HcmWorker::findByPersonnelNumber(emplCode).RecId
                    {
                        XMTrvReqReturnJson returnContract = new XMTrvReqReturnJson();
                        returnContract.ParamReqNum(reqTable.RequisitionNumber);
                        returnContract.ParamTrvPurpose(reqTable.TravelPurpose);
                        returnContract.ParamReqStatus(enum2Str(reqTable.ApprovalStatus));
                        resultSet.addEnd(returnContract);
                    }
                }
            }
    
        }
        catch (Exception::CLRError)
        {
            jsread = resultSet.addEnd(strfmt('%1',AifUtil::getClrErrorMessage()));
        }
        catch (Exception::Error)
        {
            jsread = resultSet.addEnd(strfmt("Exception::Error caught"));
        }
        
        jsread = FormJsonSerializer::serializeClass(resultSet);
        return jsread;
    }
  • Suggested answer
    Martin Dráb Profile Picture
    237,801 Most Valuable Professional on at

    Anyway, now I see that your input isn't even valid JSON. You seem to mean this:

    {
        "record":
        [
            {
                "Company":"USMF",
                "Emplcode":"000020"
            }
        ]
    }
  • MohitParkash Profile Picture
    35 on at

    Dear Martin,

    Thanks  a lot this work like charm.

    I have modified my json :

    {

    "record":

    [

    {

    "Company":"USMF",

    "Emplcode":"000020"

    }

    ]

    }

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

November Spotlight Star - Khushbu Rajvi

Congratulations to a top community star!

Forum Structure Changes Coming on 11/8!

In our never-ending quest to help the Dynamics 365 Community members get answers faster …

Dynamics 365 Community Platform update – Oct 28

Welcome to the next edition of the Community Platform Update. This is a status …

Leaderboard > Finance

Last 30 days Overall leaderboard

Featured topics

Product updates

Dynamics 365 release plans