Serialization of enum types

Situation: A web service hosted on Dynamics AX 2012 AOS; it finds some data in database on demand and returns them. The type of one of the fields is UtilElementType enum.

Problem: If no record is found, system throws the exception “Enum value ‘0’ is invalid for type ‘Dynamics.Ax.Application.UtilElementType’ and cannot be serialized.”

Analysis: Fortunately, the text of the exception precisely describes the problem. The field contains its default value (0), which is unfortunately not a valid value of UtilElementType enum (the lowest valid value is 1 – DisplayTool). That’s in fact fine with both X++ and C# (I don’t know how it is with other .NET languages), but the serializer is stricter about this.

Solution:The best solution would be to use a nullable type, which would allow to represent the empty value simply as null.

Unfortunately, X++ does not support it directly. Nevertheless you can make your own nullable type. It basically means just to wrap up the enum type in an object, so it can have value of null. And of course, it must contain appropriate attributes to make it serializable for transfer. For example:

[DataContractAttribute]
class UtilElementTypeNullable
{
    UtilElementType value;
 
    public new (UtilElementType _value)
    {
        value = _value;
    }
 
    [DataMemberAttribute]
    public UtilElementType value(UtilElementType _value = value)
    {
        value = _value;
        return value;
    }
}

Then in X++, the value assigned is null (if the enum value is 0)  or the value is wrapped to the nullable type:

contract.elementType(elementType == 0 ? null : new UtilElementTypeNullable(elementType));

Because X++ does not support generic types, it’s not possible to create something like universal Nullable<T>. It’s necessary either to create a separate class for each enum required to be nullable (it shouldn’t be a big problem, because many enums don’t require this solution) or a completely universal class containing a numeric value and ID of the type (but the used enum type wouldn’t be serialized automatically).

The last option is simply to always assign a valid value. Many enums explicitly use the element representing an empty value, typically “None” with index 0. In other cases it is possible to find another value that is normally not used and process it in a special way. For example, for UtilElementType you could use value RESERVED33.