4

I am trying to serialize some JSON input to a data contract in Microsoft Dynamics 365 Finance. A simple data contract class works fine, but I cannot get data contract extensions to work. Does any one have experience with this or perhaps a working example?

The only related information I managed to find on this topic comes from this forum post. Follow some hyperlinks and you will end up with the official Microsoft documentation (Ref# 199219), which states that this should be supported.

All variations of the data contract attributes below compile fine, but proved unsuccessful for me:

  • Using DataContract and DataMember instead of DataContractAttribute and DataMemberAttribute.
  • Combining DataContract and DataContractAttribute on a single method. (Produces runtime error about double serialization attribute.)
  • Repeating the DataContractAttribute on the extension class.

Additional experiments with the JSON deserializer class through its various constructor options also proved unsuccessful:

  • Passing a list of known types ClassA and ClassA_Extension.
  • Passing a list of known types ClassA_Extension and ClassA (in case the list order had an impact).
  • Passing a settings object and explicitly setting IgnoreExtensionDataObject to false (this appears to be the default).
  • Passing the extension class type as first parameter.

Update

A ticket was raised with Microsoft to investigate the issue. In their response they mentioned that they were able to reproduce this. They also declared that this was "by design" and "will not be fixed".

Our final solution will most likely be the following:

  1. Build a mapping of DataMemberAttribute values and the corresponding data contract method.
  2. Use a JavaScriptSerializer object to turn the JSON into a nested .NET dictionary object.
  3. Iterate over the dictionary object and populate the data contract with the help of the mapping.

Example

Below is a miminal example to demonstrate my issue. The values of the variables value1 and value2 are populated as expected, but variable value3 remains empty.

Data contract

[DataContractAttribute('Class A')]
public class ClassA
{
    protected str value1;
    protected str value2;

    [DataMemberAttribute('Value1')]
    public str value1(str _value1 = value1)
    {
        value1 = _value1;
        return value1;
    }

    [DataMemberAttribute('Value2')]
    public str value2(str _value2 = value2)
    {
        value2 = _value2;
        return value2;
    }

}

Data contract extension

[ExtensionOf(classStr(ClassA))]
public final class ClassA_Extension
{
    private str value3;

    [DataMemberAttribute('Value3')]
    public str value3(str _value3 = value3)
    {
        value3 = _value3;
        return value3;
    }

}

Serialization code with hard-coded input

public class ClassTest
{
    public static void main(Args _args)
    {
        str inputJSON =   @'{
                                "Value1": "abc",
                                "Value2": "def",
                                "Value3": "ghi"
                            }';

        ClassA ret = new ClassA();

        System.IO.MemoryStream ms = new System.IO.MemoryStream(System.Text.Encoding::UTF8.GetBytes(inputJSON));

        System.Runtime.Serialization.Json.DataContractJsonSerializer dcjSer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(ret.GetType());

        ret = dcjSer.ReadObject(ms);

        ms.Close();
    }

}

Result

enter image description here

2 Answers 2

1

It looks like the serializer is having issues. You might be able to pass a Type array similar to how FormRunConfigurationPropertyClassList does it?

enter image description here

7
  • Thank you for the input! I had a look at the JSON serializer and provided some additional parameters. Unfortunately without success... I have added the things I tried to the question description.
    – Sander
    Commented Jan 24, 2020 at 9:59
  • It looks like a bug :( Commented Jan 24, 2020 at 18:23
  • 2
    That is what I feared. If I get any feedback through a Microsoft ticket, then I will update this question.
    – Sander
    Commented Jan 25, 2020 at 19:38
  • Microsoft feedback has been added as an update section in the question...
    – Sander
    Commented Feb 11, 2020 at 9:47
  • 2
    @Sander I tweeted about it to see if anyone in the AX community has any additional thoughts or workarounds. May not get traction though. twitter.com/AlexOnDAX/status/1227269448949616640?s=20 Commented Feb 11, 2020 at 16:34
1

From PU23 onwards, an inline assignment of the respective variable avoids the error "DataMemberAttributeOnExtensionClassNotSupported: The DataMemberAttribute is not supported on extension classes".

This being the case, I suggest you change your ClassA_Extension to contain the following code:

[ExtensionOf(classStr(ClassA))]
public final class ClassA_Extension
{
    // Ensure you assign a value (initializing the variable).
    private str value3 = null;

    // The rest of your code... 
}

I'm doing a similar development currently but using DataContracts for non-ChainOfCommand extensions (natural inheritance) on 10.0.37 and it works perfectly without inline assignments so unless fixed throughout the versions released this is clearly a requirement of the Chain Of Command extension.

Reference: https://erconsult.eu/blog/extending-sysoperation-contracts-with-datamemberattribute/

4
  • Thanks for your answer, but the hyperlink behind your reference points to this StackOverflow question... Could you please update your asnwer with the intended hyperlink?
    – Sander
    Commented Dec 12, 2023 at 21:24
  • Oopsies! Fixed eheh
    – CartooN
    Commented Dec 12, 2023 at 22:55
  • 1
    While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review Commented Dec 15, 2023 at 12:05
  • I'll take care of transcribing the answer tonight. New to this, thank you for the feedback @RamChander
    – CartooN
    Commented Dec 15, 2023 at 17:53

Not the answer you're looking for? Browse other questions tagged or ask your own question.