I want to use RestAPI from D365. We tried following approached
• Use newtonsoft Dll.
• Use “FormJsonSerializer“ class
And we are facing the following issue
• Unable to serialize and deserialize objects using newtonsoft dll. Always return blank object.
• We are able to serialize and deserialize object using FormJsonSerializer but if rest call contains multiple List objects then its throwing error.
[DataContract]
public final class ExUnattachedReceipt
{
private Description name;
private int amount;
private str createdDate;[DataMember('name')]
public str parmName(str _name = name)
{
name = _name;
return name;
}[DataMember('amount')]
public int parmAmount(int _amount = amount)
{
amount = _amount;
return amount;
}[DataMember('createdDate')]
public str parmCreatedDate(str _createdDate = createdDate)
{
createdDate = _createdDate;
return createdDate;
}}
We can directly call FormJsonSerializer::serializeClass(ExUnattachedReceipt);
-------------------------------------------------------------------------------------------------------------------------------------------------------------
Now lets take their another scenerio where above class is added as Collection and we want to serialize outer class
[DataContract]
public final class ExUnattachedReceiptList
{
private List exReceipts = new List(Types::Class);[DataMember('exReceipts'),
DataCollection(Types::Class, classStr(ExUnattachedReceipt))]
public List parmExReceipts(List _exReceipts = exReceipts)
{
exReceipts = _exReceipts;
return exReceipts;
}
}
In case anyone finds this. The output is empty because Newtonsoft is deliberately ignoring your data members.
The x compiler takes each DataMember attribute and makes a dotnet property out of it. That property is marked as "compiler generated", and Json.net will ignore compiler generated properties by default.
So, to serialise/deserialise an x object you have to tell Json.net to include compiler generated properties.
eg.
public static str Serialise(Object _obj) { Newtonsoft.Json.Serialization.DefaultContractResolver resolver = new Newtonsoft.Json.Serialization.DefaultContractResolver(); resolver.SerializeCompilerGeneratedMembers = true; Newtonsoft.Json.JsonSerializerSettings settings = new Newtonsoft.Json.JsonSerializerSettings(); settings.ContractResolver = resolver; return Newtonsoft.Json.JsonConvert::SerializeObject(_obj, settings); }
After trying to figure out why JSONConvert doesnt work for the last 4 hours, I ended up doing the above suggestion. Thanks a ton! Not sure why I couldnt see this in my search earlier, but definitely a saviour.
This should work:
str formatedJSON = JsonConvert::SerializeObject(JsonConvert::DeserializeObject(FormJsonSerializer::serializeClass(object)), Formatting::Indented);
Hi sohail,
can you send your solution /way of approach.? i hav similar requirement.
public class Product { public string Id { get; set; } public str Name { get; set; } }
YourCSharpLib.Product product = new YourCSharpLib.Product(); product.Id = "1"; product.Name = "Test"; str json = Newtonsoft.Json.JsonConvert::SerializeObject(product, Newtonsoft.Json.Formatting::Indented);
Show us please inbound JSON message.
If your message contain a list of your datacontracts (DC), then you have to wrap AX DC to another DC, like:
[DataContractAttribute] class DataContractClass { DataAreaId dataAreaId; List subContractList; [DataMemberAttribute('DataAreaId')] public Description parmDataAreaId(DataAreaId _dataAreaId = dataAreaId) { dataAreaId = _dataAreaId; return dataAreaId; } [DataMemberAttribute('SubContractList'), AifCollectionTypeAttribute('_subContractList', Types::Class, classStr(SubContractDataContract))] public List parmSubContractList(List _subContractList = subContractList) { subContractList = _subContractList; return subContractList; } }
====
To serialize/deserialize DC use:
DataContractClass dataContract = new DataContractClass(); dataContract.parmDataAreaId('ABCD'); List subContractDCList = new List(Types::Class); SubContractDataContract subContractDC = new SubContractDataContract(); subContractDC.parmCustomerAccount('ABCD-000001'); subContractDCList.addEnd(subContractDC); dataContract.parmProjContractList(subContractDCList); //serialize DC -> JSON str jsonSerializedContract = FormJsonSerializer::serializeClass(dataContract); //deserialize JSON -> DC Object deserializedDc = FormJsonSerializer::deserializeObject(classIdGet(dataContract), jsonSerializedContract); List deserializedSubDcList = deserializedDc.parmSubContractList(); if (deserializedSubDcList) { ListEnumerator le_DeserializedSubDc = deserializedSubDcList.getEnumerator(); while (le_DeserializedSubDc.moveNext()) { SubContractDataContract deserializedSubDc = le_DeserializedSubDc.current(); //Actions with subDC } }
Hi
There is another easy way to handle your case.. if you can consume web service from C# client and only get response on D365.
We have the same requirement previously in one of our project. To achieve this We created everything in C# project even the attribute classes and consume the services as well with in C#.
Then add the reference of the C# project DLLs in D365FO and call the method to consume the service. even all type of serialization we were performing on C# end.
If you are still facing any issue do let me know we can discuss this in detail.
It should be nothing with D365. You can debug into the newtonsoft.dll to see why the method returns empty string.
We have created the Class as
[DataContractAttribute]
public class Product
{
private str id1;
Private str name1;
[DataMemberAttribute]
public str id(str _id=id1)
{
id1 = _id;
return id1;
}
[DataMemberAttribute]
public str name(str _name=name1)
{
name1 = _name;
return name1;
}
}
Create on runnable call and added following code
Str json;
product = new Product();
product.id("1");
product.name("Test");
json = Newtonsoft.Json.JsonConvert::SerializeObject(product,Newtonsoft.Json.Formatting::Indented);
info (json);
Newton soft always return blank Json string.
Stay up to date on forum activity by subscribing. You can also customize your in-app and email Notification settings across all subscriptions.
André Arnaud de Cal... 290,900 Super User 2024 Season 2
Martin Dráb 229,275 Most Valuable Professional
nmaenpaa 101,156