JSON to X++ Classes the easy way

Calling API’s that expect and return JSON from within X++ has become fairly routine and simple with the release of Dynamics 365 for Operations. Recently we moved a module written in C# that resided as external DLL’s within AX, to an Azure-based API that talks JSON via REST. Calling the API was fairly straightforward but manipulating the JSON between X++ and the API seemed like a lot of manual work requiring get/set operations for each property.

Assume you have a class in X++ containing a number of properties, similar to this one below.

class PFLPayrollResultsRequest
{
    str customerID;
    str appKey;
    str legalEntity;
    str payRunNumber;
 
    public str CustomerID(str _customerID = customerID)
    {
        customerID = _customerID;
        return customerID;
    }
 
    public str AppKey(str _appKey = appKey)
    {
        appKey = _appKey;
        return appKey;
    }
 
    public str LegalEntity(str _legalEntity = legalEntity)
    {
        legalEntity = _legalEntity;
        return legalEntity;
    }
 
    public str PayRunNumber(str _payRunNumber = payRunNumber)
    {
        payRunNumber = _payRunNumber;
        return payRunNumber;
    }
}

 

This class might be used for data retrieval and storage within X++, and let’s assume at some point we want to send the state to an external API using JSON. At first glance it seems that we would have to access each individual property and retrieve it from the class, build the JSON string up from that, and then submit that across the wire. The NewtonSoft library gives us a fair bit of methods to work with, however that is external to X++, and NewtonSoft does not understand X++ classes. When the API call returns, it might contain thousands of records which then have to be loaded into X++ classes, property by property.

The solution lies in using the FormJsonSerializer class. Simply decorate your X++ class with a number of attributes (DataContractAttribute, DataMemberAttribute) as shown below:

[DataContractAttribute]
class PFLPayrollResultsRequest
{
    str customerID;
    str appKey;
    str legalEntity;
    str payRunNumber;
 
    [DataMemberAttribute]
    public str CustomerID(str _customerID = customerID)
    {
        customerID = _customerID;
        return customerID;
    }
 
    [DataMemberAttribute]
    public str AppKey(str _appKey = appKey)
    {
        appKey = _appKey;
        return appKey;
    }
 
    [DataMemberAttribute]
    public str LegalEntity(str _legalEntity = legalEntity)
    {
        legalEntity = _legalEntity;
        return legalEntity;
    }
 
    [DataMemberAttribute]
    public str PayRunNumber(str _payRunNumber = payRunNumber)
    {
        payRunNumber = _payRunNumber;
        return payRunNumber;
    }
}

 

Now we can serialize this class to a JSON string for transfer, and also load an X++ class with the JSON result set returned. A quick example is shown below, in X++.

    public static void GetTempTrans()
    {
        System.Net.WebClient webClient;
        System.Text.UTF8Encoding encoder;
       
        try
        {
            PFLPayrollResultsRequest request = new PFLPayrollResultsRequest(); - this is the request class we convert to JSON and send to the API
            request.AppKey("232B8D90-7C3BF92DEA9F");
            request.CustomerID("27C2C06F8C2737");
            request.LegalEntity("AUP");
            request.PayRunNumber("12345");
 
            webClient = new System.Net.WebClient();
            System.Net.WebHeaderCollection headers = webClient.Headers;
            headers.Add("Content-Type", "application/json");
            encoder = new System.Text.UTF8Encoding();
            str json = FormJsonSerializer::serializeClass(request);// use this AX helper class (FormJsonSerializer) to convert to JSON here
            System.Byte[] encodedBytes = encoder.GetBytes(json);
            System.Byte[] response = webClient.UploadData("https://www.myapi.com/api/Engine/Post/TemporaryResults", encodedBytes);
            str jsonResponse = webClient.Encoding.GetString(response); 
            // deserialize result returned from API here using FormJsonSerializer::deserializeClass();
        }
        catch
        {
        } 
    }
Advertisements

2 thoughts on “JSON to X++ Classes the easy way

  1. Hi guys, i have added a new class taken from D365 FFO and added to AX2012 with minor modifications, so you can easily pass any data contract (even nested) to serialize deserialize to JSON
    FIRST CREATE THIS CLASS

    ///

    /// Attribute to decorate a serializable collection property.

    ///

    public class SMCDataCollectionAttribute extends SysAttribute

    {

    Types _itemType;

    str _itemTypeName;

    }

    public Types itemType()

    {

    return _itemType;

    }

    public str itemTypeName()

    {

    return _itemTypeName;

    }

    public void new(Types itemType, str itemTypeName = ”)

    {

    super();

    _itemType = itemType;

    _itemTypeName = itemTypeName;

    }

    THEN THIS CLASS

    ///

    /// taken from D365 finance and operations

    ///

    ///

    /// AJS//

    ///

    class SMCFormJsonSerializer

    {

    System.IO.StringWriter stringWriter;

    Newtonsoft.Json.JsonTextWriter jsonWriter;

    str nullPlaceholder;

    utcDateTime dateTimeBase;

    Map theDataContractClass;

    MapEnumerator theDataContractClassEnumerator;

    }

    ///

    /// flush the map object cache

    ///

    public void flushCache()

    {

    theDataContractClass = null;

    }

    private str json()

    {

    str json;

    json = stringWriter.ToString();

    json = strReplace(json, strFmt(‘”%1″‘, nullPlaceholder), ‘null’);

    return json;

    }

    private void new()

    {

    stringWriter = new System.IO.StringWriter();

    jsonWriter = new Newtonsoft.Json.JsonTextWriter(stringWriter);

    nullPlaceholder = guid2str(newGuid());

    dateTimeBase = SMCFormJsonSerializer::dateTimeBase();

    }

    private void serializeArray(Array _array)

    {

    Types arrayItemType;

    int arrayIndex;

    if (_array == null)

    {

    jsonWriter.WriteValue(nullPlaceholder);

    return;

    }

    jsonWriter.WriteStartArray();

    arrayItemType = _array.typeId();

    for(arrayIndex = 1; arrayIndex <= _array.lastIndex(); arrayIndex++)

    {

    if (arrayItemType == Types::Class)

    {

    this.serializeObject(_array.value(arrayIndex));

    }

    else

    {

    this.writePrimitiveValue(arrayItemType, _array.value(arrayIndex));

    }

    }

    jsonWriter.WriteEndArray();

    }

    private void serializeDataContract(Object _dataContract)

    {

    SysDictClass dictClass;

    DataContractAttribute dataContractAttribute;

    DataMemberAttribute dataMemberAttribute;

    Set methods;

    SetEnumerator se;

    SysDictMethod dictMethod;

    str dataMemberName;

    Object dataMemberValueObject;

    container dataMemberValuePrimitive;

    container memberValues;

    anytype memberMethodReturn;

    str memberName;

    str memberMethodName;

    ExecutePermission perm;

    Map theDataContractClassMember;

    MapEnumerator theDataContractClassMemberEnumerator;

    theDataContractClassMember = new Map(Types::String, Types::AnyType);

    if (theDataContractClass == null)

    {

    theDataContractClass = new Map(Types::string, Types::AnyType);

    }

    jsonWriter.WriteStartObject();

    dictClass = new SysDictClass(classIdGet(_dataContract));

    dataContractAttribute = dictClass.getAttribute(classStr(DataContractAttribute));

    if (dataContractAttribute == null)

    {

    throw error(strFmt("@SYS134831", dictClass.name(), dictClass.id()));

    }

    perm = new ExecutePermission();

    if(perm)

    {

    perm.assert();

    }

    // check if it exists if not create it

    if (!theDataContractClass.exists(dictClass.name()))

    {

    methods = dictClass.methods(true, false, true);

    se = methods.getEnumerator();

    while (se.moveNext())

    {

    dictMethod = se.current();

    dataMemberAttribute = dictMethod.getAttribute(classStr(DataMemberAttribute));

    if (dataMemberAttribute != null)

    {

    dataMemberName = dataMemberAttribute.Name();

    if (!dataMemberName)

    {

    dataMemberName = dictMethod.name();

    }

    memberValues = [dataMemberName, dictMethod.name(), dictMethod.returnType()];

    [ memberName, memberMethodName, memberMethodReturn] = memberValues;

    jsonWriter.WritePropertyName(memberName);

    if (memberMethodReturn == Types::Class)

    {

    this.serializeObject(dictClass.callObject(memberMethodName, _dataContract));

    }

    else

    {

    this.writePrimitiveValue(memberMethodReturn, dictClass.callObject(memberMethodName, _dataContract));

    }

    }

    }

    }

    CodeAccessPermission::revertAssert();

    jsonWriter.WriteEndObject();

    /*

    theDataContractClassMember = theDataContractClass.lookup(dictClass.name());

    theDataContractClassMemberEnumerator = new MapEnumerator(theDataContractClassMember);

    while (theDataContractClassMemberEnumerator.moveNext())

    {

    [ memberName, memberMethodName, memberMethodReturn] = theDataContractClassMemberEnumerator.currentValue();

    jsonWriter.WritePropertyName(memberName);

    if (memberMethodReturn == Types::Class)

    {

    this.serializeObject(dictClass.callObject(memberMethodName, _dataContract));

    }

    else

    {

    this.writePrimitiveValue(memberMethodReturn, dictClass.callObject(memberMethodName, _dataContract));

    }

    }

    jsonWriter.WriteEndObject();

    */

    }

    private void serializeList(List _list)

    {

    Types listItemType;

    ListEnumerator le;

    if (_list == null)

    {

    jsonWriter.WriteValue(nullPlaceholder);

    return;

    }

    jsonWriter.WriteStartArray();

    listItemType = _list.typeId();

    le = _list.getEnumerator();

    while (le.moveNext())

    {

    if (listItemType == Types::Class)

    {

    this.serializeObject(le.current());

    }

    else

    {

    this.writePrimitiveValue(listItemType, le.current());

    }

    }

    jsonWriter.WriteEndArray();

    }

    private void serializeObject(Object _object)

    {

    ClassId classId;

    if (_object == null)

    {

    jsonWriter.WriteValue(nullPlaceholder);

    return;

    }

    classId = classIdGet(_object);

    switch (classId)

    {

    case classNum(List):

    this.serializeList(_object);

    break;

    case classNum(Array):

    this.serializeArray(_object);

    break;

    default:

    this.serializeDataContract(_object);

    break;

    }

    }

    private void writeDateTimeValue(utcDateTime _value)

    {

    utcDateTime dateTimeValue;

    int64 jsDateTimeStamp;

    str jsonDateTime;

    dateTimeValue = _value;

    //jsonWriter.WriteValue(dateTimeValue);

    jsDateTimeStamp = DateTimeUtil::getDifference(dateTimeValue, dateTimeBase) * 1000;

    jsonDateTime = strFmt("\/Date(%1)\/", jsDateTimeStamp);

    jsonWriter.WriteValue(jsonDateTime);

    }

    private void writePrimitiveValue(Types valueType, anytype _value)

    {

    str strValue;

    int intValue;

    int64 int64Value;

    real realValue;

    enumId enumId;

    boolean boolValue;

    str guidValue;

    SysDictEnum dictEnum;

    if(!nullValue(_value))

    {

    valueType = typeOf(_value);

    }

    switch (valueType)

    {

    case Types::String:

    strValue = _value;

    jsonWriter.WriteValue(strValue);

    break;

    case Types::Integer:

    intValue = _value;

    jsonWriter.WriteValue(intValue);

    break;

    case Types::Int64:

    int64Value = _value;

    jsonWriter.WriteValue(int64Value);

    break;

    case Types::Real:

    realValue = _value;

    jsonWriter.WriteValue(realValue);

    break;

    case Types::UtcDateTime:

    this.writeDateTimeValue(_value);

    break;

    case Types::Date:

    this.writeDateTimeValue(DateTimeUtil::newDateTime(_value, 0));

    break;

    case Types::Enum:

    enumId = DictEnum::value2id(_value);

    if (enumId == enumNum(boolean))

    {

    boolValue = _value;

    jsonWriter.WriteValue(boolValue);

    }

    else

    {

    dictEnum = new SysDictEnum(enumId);

    if (dictEnum != null)

    {

    strValue = dictEnum.value2Symbol(_value);

    jsonWriter.WriteValue(strValue);

    }

    else

    {

    throw error(strFmt("@SYS57821", enumId));

    }

    }

    break;

    case Types::Guid:

    guidValue = guid2str(_value);

    jsonWriter.WriteValue(guidValue);

    break;

    default:

    throw error(strFmt("@SYS73815", valueType));

    }

    }

    private static utcdatetime dateTimeBase()

    {

    return DateTimeUtil::newDateTime(1\1\1970, 0);

    }

    ///

    /// Deserializes a collection of strongly typed items. The supported collection types are

    /// List and Array

    ///

    public static Object deserializeCollection(ClassId _collectionTypeId, str _serializedValue, Types _itemType, str _itemTypeName = ”)

    {

    System.IO.StringReader stringReader;

    Newtonsoft.Json.JsonTextReader jsonReader;

    Object deserializedCollection = null;

    stringReader = new System.IO.StringReader(_serializedValue);

    jsonReader = new Newtonsoft.Json.JsonTextReader(stringReader);

    //jsonReader.DateParseHandling = Newtonsoft.Json.DateParseHandling::None;

    jsonReader.set_DateParseHandling(Newtonsoft.Json.DateParseHandling::None);

    while(deserializedCollection == null && jsonReader.Read())

    {

    //if (jsonReader.TokenType == Newtonsoft.Json.JsonToken::StartArray)

    if (jsonReader.get_TokenType() == Newtonsoft.Json.JsonToken::StartArray)

    {

    deserializedCollection = SMCFormJsonSerializer::deserializeCollectionInternal(_collectionTypeId, _itemType, _itemTypeName, jsonReader);

    }

    }

    return deserializedCollection;

    }

    ///

    /// Internal implementation of deserializing a collection of strongly typed items.

    /// Only few types of collections are supported

    ///

    private static Object deserializeCollectionInternal(ClassId _collectionTypeId, Types _itemType, str _itemTypeName, Newtonsoft.Json.JsonTextReader jsonReader)

    {

    Object deserializedCollection;

    List deserializedList;

    Array deserializedArray;

    anytype deserializedItem;

    boolean continueReading;

    int itemTypeId;

    // Instantiate the desired collection type

    if(_collectionTypeId == classnum(List))

    {

    deserializedList = new List(_itemType);

    deserializedCollection = deserializedList;

    }

    else if(_collectionTypeId == classnum(Array))

    {

    deserializedArray = new Array(_itemType);

    deserializedCollection = deserializedArray;

    }

    // Resolve the item type name to the right type ID

    if(_itemType == Types::Class)

    {

    itemTypeId = className2Id(_itemTypeName);

    }

    else if(_itemType == Types::Enum)

    {

    itemTypeId = enumName2Id(_itemTypeName);

    }

    continueReading = true;

    while(continueReading && jsonReader.Read())

    {

    deserializedItem = null;

    //if (jsonReader.TokenType == Newtonsoft.Json.JsonToken::EndArray)

    if (jsonReader.get_TokenType() == Newtonsoft.Json.JsonToken::EndArray)

    {

    // Reached the end of the current array

    continueReading = false;

    }

    //else if (jsonReader.TokenType == Newtonsoft.Json.JsonToken::StartObject)

    else if (jsonReader.get_TokenType() == Newtonsoft.Json.JsonToken::StartObject)

    {

    // Deserialize the object

    deserializedItem = SMCFormJsonSerializer::deserializeObjectInternal(itemTypeId, jsonReader);

    }

    /*

    else if (jsonReader.TokenType == Newtonsoft.Json.JsonToken::Boolean ||

    jsonReader.TokenType == Newtonsoft.Json.JsonToken::Date ||

    jsonReader.TokenType == Newtonsoft.Json.JsonToken::Float ||

    jsonReader.TokenType == Newtonsoft.Json.JsonToken::Integer ||

    jsonReader.TokenType == Newtonsoft.Json.JsonToken::String)

    */

    else if (jsonReader.get_TokenType() == Newtonsoft.Json.JsonToken::Boolean ||

    jsonReader.get_TokenType() == Newtonsoft.Json.JsonToken::Date ||

    jsonReader.get_TokenType() == Newtonsoft.Json.JsonToken::Float ||

    jsonReader.get_TokenType() == Newtonsoft.Json.JsonToken::Integer ||

    jsonReader.get_TokenType() == Newtonsoft.Json.JsonToken::String)

    {

    // Deserialize the basic type value

    //deserializedItem = SMCFormJsonSerializer::deserializeValue(_itemType, jsonReader.Value, itemTypeId);

    deserializedItem = SMCFormJsonSerializer::deserializeValue(_itemType, jsonReader.get_Value(), itemTypeId);

    }

    // If an item was deserialized, add to the collection

    if(deserializedItem != null)

    {

    if(deserializedList)

    {

    // Add to the list

    deserializedList.addEnd(deserializedItem);

    }

    else if(deserializedArray)

    {

    // Add to the array

    deserializedArray.value(deserializedArray.lastIndex() + 1, deserializedItem);

    }

    }

    }

    return deserializedCollection;

    }

    ///

    /// Deserializes an utcDateTime string.

    ///

    /// The string value to deserialize.

    /// The deserialized date and time.

    public static utcdatetime deserializeDateTime(str _value)

    {

    //const str dateMatchStr = ‘/Date(‘;

    int dateValueStartPos;

    int dateExpressionEndPos;

    int64 dateValueMS;

    utcdatetime parsedDate;

    #define.dateMatchStr(‘/Date(‘)

    if (strScan(_value, #dateMatchStr, 1, strLen(_value)) == 1)

    {

    dateValueStartPos = strLen(#dateMatchStr) + 1;

    dateExpressionEndPos = strScan(_value, ‘)’, 0, strLen(_value));

    if (dateExpressionEndPos > dateValueStartPos)

    {

    dateValueMS = str2Int64(subStr(_value, dateValueStartPos, dateExpressionEndPos – dateValueStartPos));

    return DateTimeUtil::addSeconds(SMCFormJsonSerializer::dateTimeBase(), dateValueMS div 1000);

    }

    }

    parsedDate = DateTimeUtil::parse(_value);

    return parsedDate;

    }

    ///

    /// Deserializes an object of a given type. Only the data-member attrbuted properties are deserialized.

    ///

    public static Object deserializeObject(ClassId _objectTypeId, str _serializedValue)

    {

    System.IO.StringReader stringReader;

    Newtonsoft.Json.JsonTextReader jsonReader;

    Object deserializedObject = null;

    stringReader = new System.IO.StringReader(_serializedValue);

    jsonReader = new Newtonsoft.Json.JsonTextReader(stringReader);

    //jsonReader.DateParseHandling = Newtonsoft.Json.DateParseHandling::None;

    jsonReader.set_DateParseHandling(Newtonsoft.Json.DateParseHandling::None);

    while(deserializedObject == null && jsonReader.Read())

    {

    //if(jsonReader.TokenType == Newtonsoft.Json.JsonToken::StartObject)

    if(jsonReader.get_TokenType() == Newtonsoft.Json.JsonToken::StartObject)

    {

    deserializedObject = SMCFormJsonSerializer::deserializeObjectInternal(_objectTypeId, jsonReader);

    }

    }

    return deserializedObject;

    }

    ///

    /// Internal implementatino of deserializing an object of a given type. Only the data-member attrbuted properties are deserialized.

    ///

    private static Object deserializeObjectInternal(ClassId _objectTypeId, Newtonsoft.Json.JsonTextReader jsonReader)

    {

    SysDictClass objectType = new SysDictClass(_objectTypeId);

    Set objectMethods;

    SysDictMethod objectMethod;

    SetEnumerator se;

    str currentJsonProperty;

    str dataMemberName;

    anytype propertyValue;

    DataMemberAttribute memberAttribute;

    //DataCollectionAttribute collectionAttribute;

    SMCDataCollectionAttribute collectionAttribute;

    Map dataMembers = new Map(Types::String, Types::Class);

    Object deserializedObject = objectType.makeObject();

    boolean continueReading;

    Types returnType;

    enumId enumId;

    DictType dt;

    // Find all valid data members on this type

    objectMethods = objectType.methods(true, false, true);

    se = objectMethods.getEnumerator();

    while (se.moveNext())

    {

    objectMethod = se.current();

    memberAttribute = objectMethod.getAttribute(classStr(DataMemberAttribute));

    if (memberAttribute != null)

    {

    dataMemberName = memberAttribute.Name();

    if (!dataMemberName)

    {

    dataMemberName = objectMethod.name();

    }

    dataMembers.insert(dataMemberName, objectMethod);

    }

    }

    continueReading = true;

    while(continueReading && jsonReader.Read())

    {

    //if (jsonReader.TokenType == Newtonsoft.Json.JsonToken::EndObject)

    if (jsonReader.get_TokenType() == Newtonsoft.Json.JsonToken::EndObject)

    {

    // Reached the end of the current object

    continueReading = false;

    }

    //else if (jsonReader.TokenType == Newtonsoft.Json.JsonToken::PropertyName)

    else if (jsonReader.get_TokenType() == Newtonsoft.Json.JsonToken::PropertyName)

    {

    // This is identifying a property

    //currentJsonProperty = jsonReader.Value;

    currentJsonProperty = jsonReader.get_Value();

    }

    //else if (jsonReader.TokenType == Newtonsoft.Json.JsonToken::StartArray)

    else if (jsonReader.get_TokenType() == Newtonsoft.Json.JsonToken::StartArray)

    {

    // This is the case for collection type properties

    if(currentJsonProperty)

    {

    if(dataMembers.exists(currentJsonProperty))

    {

    // Determine if the property has a colleciton attribute

    objectMethod = dataMembers.lookup(currentJsonProperty);

    collectionAttribute = objectMethod.getAttribute(classStr(SMCDataCollectionAttribute));

    if(collectionAttribute)

    {

    // Deserialize the collection

    propertyValue = SMCFormJsonSerializer::deserializeCollectionInternal(

    objectMethod.returnId(),

    collectionAttribute.itemType(),

    collectionAttribute.itemTypeName(),

    jsonReader);

    // Set the property

    objectType.callObject(objectMethod.name(), deserializedObject, propertyValue);

    }

    }

    }

    }

    //else if (jsonReader.TokenType == Newtonsoft.Json.JsonToken::StartObject)

    else if (jsonReader.get_TokenType() == Newtonsoft.Json.JsonToken::StartObject)

    {

    // This is the case for nested complex type properties

    if(currentJsonProperty)

    {

    if(dataMembers.exists(currentJsonProperty))

    {

    // Read the object from JSON

    objectMethod = dataMembers.lookup(currentJsonProperty);

    // Desrialize the object property

    propertyValue = SMCFormJsonSerializer::deserializeObjectInternal(objectMethod.returnId(), jsonReader);

    // Set the proeprty value

    objectType.callObject(objectMethod.name(), deserializedObject, propertyValue);

    }

    }

    }

    /*

    else if (jsonReader.TokenType == Newtonsoft.Json.JsonToken::Boolean ||

    jsonReader.TokenType == Newtonsoft.Json.JsonToken::Date ||

    jsonReader.TokenType == Newtonsoft.Json.JsonToken::Float ||

    jsonReader.TokenType == Newtonsoft.Json.JsonToken::Integer ||

    jsonReader.TokenType == Newtonsoft.Json.JsonToken::String)

    */

    else if (jsonReader.get_TokenType() == Newtonsoft.Json.JsonToken::Boolean ||

    jsonReader.get_TokenType() == Newtonsoft.Json.JsonToken::Date ||

    jsonReader.get_TokenType() == Newtonsoft.Json.JsonToken::Float ||

    jsonReader.get_TokenType() == Newtonsoft.Json.JsonToken::Integer ||

    jsonReader.get_TokenType() == Newtonsoft.Json.JsonToken::String)

    {

    // This is the case for basic type values

    //if(jsonReader.Value && deserializedObject && currentJsonProperty)

    if(jsonReader.get_Value() && deserializedObject && currentJsonProperty)

    {

    if(dataMembers.exists(currentJsonProperty))

    {

    objectMethod = dataMembers.lookup(currentJsonProperty);

    //Types returnType = objectMethod.returnType();

    returnType = objectMethod.returnType();

    //enumId enumId = objectMethod.returnId();

    enumId = objectMethod.returnId();

    if (returnType == Types::UserType)

    {

    // Get the base type for extended data type

    returnType = extendedTypeId2Type(objectMethod.returnId());

    if (returnType == Types::Enum)

    {

    // Get the enumId for enum EDT types

    //DictType dt = new DictType(objectMethod.returnId());

    enumId = dt.enumId();

    }

    }

    // Deserialize primitive value

    propertyValue = SMCFormJsonSerializer::deserializeValue(

    returnType,

    //jsonReader.Value,

    jsonReader.get_Value(),

    enumId);

    // Set the property value

    objectType.callObject(objectMethod.name(), deserializedObject, propertyValue);

    }

    }

    }

    }

    return deserializedObject;

    }

    ///

    /// Deserializes a primitive value from its string representation.

    ///

    public static anytype deserializeValue(Types _type, str _value, enumId _enum = 0)

    {

    anytype typedValue = null;

    int64 int64value;

    int intvalue;

    real realvalue;

    switch (_type)

    {

    case Types::Date:

    {

    //iso date format to x++ date format

    typedValue = str2Date(_value, 321); break;

    }

    case Types::Enum: typedValue = symbol2Enum(_enum, _value); break;

    case Types::Guid: typedValue = str2Guid(_value); break;

    case Types::Int64:

    {

    //int64 int64value = System.Int64::Parse(_value, System.Globalization.CultureInfo::InvariantCulture);

    int64value = System.Int64::Parse(_value, System.Globalization.CultureInfo::get_InvariantCulture());

    typedValue = int64value;

    break;

    }

    case Types::Integer:

    {

    //int intvalue = System.Int32::Parse(_value, System.Globalization.CultureInfo::InvariantCulture);

    intvalue = System.Int32::Parse(_value, System.Globalization.CultureInfo::get_InvariantCulture());

    typedValue = intvalue;

    break;

    }

    case Types::Real:

    {

    //real realvalue = System.Decimal::Parse(_value, System.Globalization.CultureInfo::InvariantCulture);

    realvalue = System.Decimal::Parse(_value, System.Globalization.CultureInfo::get_InvariantCulture());

    typedValue = realvalue;

    break;

    }

    case Types::String: typedValue = _value; break;

    case Types::VarString: typedValue = _value; break;

    case Types::Time: typedValue = str2time(_value); break;

    case Types::UtcDateTime: typedValue = SMCFormJsonSerializer::deserializeDateTime(_value); break;

    default:

    // Any other kind of type is illegal for setting

    throw error(“The type of object cannot be set.”);

    }

    return typedValue;

    }

    public static str normalizeNameForJSON(str inputString)

    {

    // this function must sync with NormalizeNameForJSON in %INETROOT%\Source\Kernel\Source\FormDataSourceInteraction.cpp

    int pos = strfind(inputString, ‘[‘, 1, strlen(inputString));

    if(pos > 0)

    {

    inputString = strDel(inputString, pos, 1);

    inputString = strIns(inputString, ‘_’, pos);

    pos = strfind(inputString, ‘]’, 1, strlen(inputString));

    if(pos > 0)

    {

    inputString = strDel(inputString, pos, 1);

    }

    }

    pos = strfind(inputString, ‘ ‘, 1, strlen(inputString));

    if(pos > 0)

    {

    inputString = strDel(inputString, pos, 1); // remove spaces in fieldname since they cause serialization error

    }

    return inputString;

    }

    public static str serializeClass(Object _object)

    {

    SMCFormJsonSerializer serializer;

    if (_object == null)

    {

    return ‘null’;

    }

    serializer = new SMCFormJsonSerializer();

    serializer.serializeObject(_object);

    return serializer.json();

    }

    public static str serializePrimitive(anytype propertyValue, enumId _enum = 0)

    {

    Types valueType;

    System.String strValue;

    System.Int32 intValue;

    System.Int64 int64Value;

    System.Decimal realValue;

    if(propertyValue != null)

    {

    valueType = typeOf(propertyValue);

    }

    switch (valueType)

    {

    case Types::Integer:

    intValue = propertyValue;

    //strValue = intValue.ToString(System.Globalization.CultureInfo::InvariantCulture);

    strValue = intValue.ToString(System.Globalization.CultureInfo::get_InvariantCulture());

    return strValue;

    case Types::Int64:

    int64Value = propertyValue;

    //strValue = int64Value.ToString(System.Globalization.CultureInfo::InvariantCulture);

    strValue = int64Value.ToString(System.Globalization.CultureInfo::get_InvariantCulture());

    return strValue;

    case Types::Real:

    realValue = propertyValue;

    //strValue = realValue.ToString(System.Globalization.CultureInfo::InvariantCulture);

    strValue = realValue.ToString(System.Globalization.CultureInfo::get_InvariantCulture());

    return strValue;

    case Types::Time:

    // x++ timeOfDay

    int64Value = propertyValue;

    //strValue = int64Value.ToString(System.Globalization.CultureInfo::InvariantCulture);

    strValue = int64Value.ToString(System.Globalization.CultureInfo::get_InvariantCulture());

    return strValue;

    case Types::UtcDateTime:

    //x++ utcdatetime format yyyy-mm-ddThh:mm:ss to iso datetime format

    return DateTimeUtil::toStr(propertyValue);

    case Types::Date:

    //x++ date format to iso date format yyyy-mm-dd

    strValue = date2str(propertyValue,321,DateDay::Digits2,DateSeparator::Hyphen,DateMonth::Digits2,DateSeparator::Hyphen,DateYear::Digits4);

    return strValue;

    case Types::Enum:

    if (_enum)

    {

    return enum2Symbol(_enum, propertyValue);

    }

    else

    {

    return strFmt(‘%1’, propertyValue);

    }

    default:

    return strFmt(‘%1’, propertyValue);

    }

    }

    AFTER ALL YOU CAN SERIALIZE TO JSON LIKE BELOW

    contract.parmArabicName(unitOfMeasure.Symbol);
    contract.parmMFQBusinessLine(‘2’); //always 2 for now
    contract.parmEnglishName(unitOfMeasure.Symbol);
    contract.parmIntegrationKey(unitOfMeasureDetails.SMCIntegrationKey);

    jsonMessageStr = SMCFormJsonSerializer::serializeClass(contract);

    Liked by 1 person

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s