Search code examples
c#.netjsonjson.netdeserialization

C# Enum deserialization with Json.Net: Error converting value to type


I'm using Json.NET to serialize/deserialize some JSON APIs.

The API response have some integer values that map to an Enum defined in the application.

The enum is like this:

public enum MyEnum
{
    Type1,
    Type2,
    Type3
}

and the JSON API response has the following:

{
    "Name": "abc",
    "MyEnumValue":"Type1"
}

sometimes the API returns a value for the MyEnumValue field that's not defined in my enum, like this:

{
    "Name": "abc",
    "MyEnumValue":"Type4"
}

That throws an exception:

Error converting value "Type4" to type 'MyEnum'

Is there a way to handle this error by assigning a default value or something to avoid the application crash?


Solution

  • Let's say we have the following json string:

    [
        {
            "Name": "abc",
            "MyEnumValue": "Type1"
        },
        {
            "Name": "abcd",
            "MyEnumValue": "Type2"
        },
        {
            "Name": "abcde",
            "MyEnumValue": "Type3"
        }    ,
        {
            "Name": "abcdef",
            "MyEnumValue": "Type4"
        }
    ]
    

    and the following class and enum:

    public class MyClass
    {
        public string Name { get; set; }
    
        public MyEnum MyEnumValue { get; set; }
    }
    
    public enum MyEnum
    {
        Type1,
        Type2,
        Type3
    }
    

    As it can be noticed, the json string array contains item (the last one), that cannot be correctly mapped to the MyEnum. To avoid deserialization errors you can use the following code snippet:

    static void Main(string[] args)
    {         
        var serializationSettings = new JsonSerializerSettings
        {
            Error = HandleDeserializationError
        };
    
        var lst = JsonConvert.DeserializeObject<List<MyClass>>(jsonStr, serializationSettings);
    }
    
    public static void HandleDeserializationError(object sender, ErrorEventArgs errorArgs)
    {
        errorArgs.ErrorContext.Handled = true;
        var currentObj = errorArgs.CurrentObject as MyClass;
    
        if (currentObj == null) return;
        currentObj.MyEnumValue = MyEnum.Type2;            
    }
    

    where the jsonStr variable is the posted json string above. In the above code sample, if MyEnumValue cannot be correctly interpreted, it is set to a default value of Type2.

    Example: https://dotnetfiddle.net/WKd2Lt