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 / Serialize X++ objects ...
Finance forum

Serialize X++ objects to JSON

(0) ShareShare
ReportReport
Posted on by

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.

I have the same question (0)
  • Martin Dráb Profile Picture
    237,976 Most Valuable Professional on at

    It seems that the title is wrong; you seem to have a problem with JSON (de-)serialization, not with Rest API.

    Newtonsoft.Json is what the whole world uses, including FormJsonSerializer. Please give us more details about how you're using it; it's hard to spot bugs in code that we've never seen.

  • Community Member Profile Picture
    on at

    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.

  • Jie G Profile Picture
    on at

    It should be nothing with D365. You can debug into the newtonsoft.dll to see why the method returns empty string.

  • Sheikh Sohail Profile Picture
    6,125 on at

    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.

  • Suggested answer
    Sasha Dudarenko Profile Picture
    50 on at

    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
        }
    }
  • Suggested answer
    Martin Dráb Profile Picture
    237,976 Most Valuable Professional on at
    I can confirm that directly using JsonConvert::SerializeObject() doesn't work for me with normal X++ objects. I didn't investigate why; a simple workaround is defining the class in C# and using properties. Your Product class could look like this:
    public class Product
    {
        public string Id { get; set; }
        public str Name { get; set; }
    }
    (This is even shorter than your original code.)
    Then you can use create an instance in X++, fill it with data and pass it to JsonConvert::SerializeObject() in X++. Like this:
    YourCSharpLib.Product product = new YourCSharpLib.Product();
    product.Id = "1";
    product.Name = "Test";
    
    str json = Newtonsoft.Json.JsonConvert::SerializeObject(product, Newtonsoft.Json.Formatting::Indented);
    By the way, it's now clear that the problem isn't related to Rest API, therefore let me change the title from "RestAPI from D365" to something more fitting.
  • TestBot Profile Picture
    950 on at

    Hi sohail,

    can you send your solution /way of approach.?  i hav similar requirement.

  • Suggested answer
    M.K. Profile Picture
    10 on at

    This should work:

    str formatedJSON = JsonConvert::SerializeObject(JsonConvert::DeserializeObject(FormJsonSerializer::serializeClass(object)), Formatting::Indented);

  • 0993BV Profile Picture
    on at

    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.

  • Suggested answer
    Mat Fergusson Profile Picture
    7 on at

    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);
        }

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