I have sent a JSON string through an HTTP call over to my post event handler. I want to take that string and populate the corresponding x++ object I have created in my post event handler. Does x++ have a library or methods that can take a string representation of an object and use it to populate the fields of a declared object? Basically, does x++ have it's own version of GSON/JSON? If not, is there a way to go about doing this?
*This post is locked for comments
You could use FormJsonSerializer::deserializeCollection.
public class RecordContract
{
List fieldValues;
[DataMember. DataCollectionAttribute(Types::Class, classStr(FieldValueContract))]
public List Records(List __fieldValues= fieldValues)
{
fieldValues= __fieldValues;
return fieldValues;
}
}
[DataContract]
class FieldValueContract
{
FieldName fieldName;
FieldValue fieldValue;
[DataMember]
public FieldName FieldName(FieldName _fieldName= fieldName)
{
fieldName = _fieldName;
return fieldName;
}
[DataMember]
public FieldValue FieldValue(FieldValue _fieldValue = fieldValue)
{
fieldValue = _fieldValue;
return fieldValue;
}
}
List records = FormJsonSerializer::deserializeCollection(classNum(List), json, Types::Class, classStr(RecordContract));
The list is a list of Records, with the nested list populated with FieldValues.
Test using a test case - forgive the hacky code, naming, and lack of comments...it is just meant to give an idea of how to use it.
class JsonTest extends SysTestCase
{
const str json =
'[{"FieldValues": [{"FieldName": "Field1", "FieldValue"; "Rec1Field1Value"},'+
' {"FieldName": "Field2", "FieldValue": "Rec1Field2Value"}]},'+
'[{"FieldValues": [{"FieldName": "Field1", "FieldValue": "Rec2Field1Value"},'+
' {"FieldName": "Field2", "FieldValue": "Rec2Field2Value"}]}]';
[SysTestMethod]
public void JsonDeserialiseTest()
{
List records = FormJsonSerializer::deserializeCollection(classNum(List), json, Types::Class, classStr(RecordContract));
this.assertNotNull(records, "No records found in Json string");
ListEnumerator recordLe = records.getEnumerator();
RecordContract record;
FieldValueContract fieldValue;
List fieldList;
ListEnumerator fieldLe;
while (recordLe.moveNext())
{
record = recordLe.current();
fieldList = record.FieldValues();
this.assertNotNull(fieldList, 'No fields found in record element of Json string');
fieldLe = FieldList.getEnumerator();
while (fieldLe.moveNext())
{
fieldValue = fieldLe.current();
this.assertNotEqual('', fieldValue.FieldName(), 'Field was empty');
this.assertNotEqual('', fieldValue.FieldName(), 'Field value empty');
}
}
}
The title says "Object in x++" and there isn't any X++ on client-side in Dynamics 365 for Operations. All X++ code runs on server, therefore it also has access to Newtonson.Json, which is a part of the standard application.
If you're writing a client-side application, you can't use X++, so it's a completely different topic. I would limit the options to X++ if I knew that you're actually writing a client-side application in some other language. Regarding Newtonsoft.Json in such case, simply add its NuGet package to your project, as thousand developers do an a regular bases. No need to deploy it separately.
In either case, I don't see any valid argument for avoiding it. It looks more like that somebody had problems with the deployment in AX 2012 and ignores the fact that this isn't AX 2012 anymore.
There is nothing wrong with it. We wanted to develop without the 3rd party library. This is client side code that we need to package and deploy. When we integrated with AX2012 in the past, the packaging and deploying of the Newtonsoft code was done separately(I didn't work with this so I don't know as to why). The other developers wanted me to try and come up with a solution that didn't involve Newtonsoft for that reason. Actually the serialization that we did prior to take an object and turn it into a Json string was using Data Contract. This solution was provided to us by you Martin. We weren't sure if the was a deserialization until I came across the link I posted.
Sure, you can DataContractJsonSerializer or any other JSON serializer (as long as it has all the features you need).
Nevertheless why isn't Newtonsoft.Json good enough for you, if it's good enough for Microsoft and it's already used in AX? What problem do you see in using it?
Dear Martin,
Thank you for the response. I didn't end up using Newtonsoft as I didn't want to involve a 3rd party, but looking into deserializers I came accross this link from AX 2012 which was still applicable in the AX 7 environment. I will post the link below in case other people developing want to created Json strings from objects or objects to Json strings.
msdn.microsoft.com/.../bb412179(v=vs.110).aspx
(Note: this is C# code so in your solution Explorer you would need to include C#. Also the class that you put under the Data contract can be in your x++ code. In the example in the link its on the C# code)
JSON (Java Script Object Notation) is a standardized data format. There is nothing like "your own JSON"; you either use JSON format according to the standard or you have your own format (= not JSON).
Maybe you meant a JSON deserializer? If so, you're making a mistake in limiting yourself to X++. We're not in the .NET world, so you can use any CLI-compliant language. Why would you mind which language was used to write the (de)serializer? As long as it can work with CIL types, you're all right.
To be a bit more specific, you can directly use classes from Newtonsoft.Json in your X++ code. Look at FormJsonSerializer::deserializeObject(), which you can also use directly if it meets your requirements.
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... 291,253 Super User 2024 Season 2
Martin Dráb 230,188 Most Valuable Professional
nmaenpaa 101,156