Newtonsoft.json: Problem when deserializing enums with different names

Created on 7 Nov 2014  ·  4Comments  ·  Source: JamesNK/Newtonsoft.Json

I've noticed a problem when deserializing enums (and using different names) when deserializing enums

for instance if i have a value from json called value_a and in c# i have ValueA

public enum EnumA
{
[EnumMember(Value = "value_a")]
ValueA
}

Enum member Value wont be used and deserialization will fail

on the other hand if its a normal value for instance

public class Address
{
    [DataMember(Name = "address_1")]
    public string AddressLine1 { get; set; }

}

This will work fine.

Upon investigation it seems that for enum json.net uses internally enum.tryparse which doesnt use the enummember attribute.

If json.net could be fixed in that manner so that enummember value could be used that would be great

Most helpful comment

After checking the code and doing some research the best option you have is to set your enum like this:

[DataContract]
[JsonConverter(typeof(StringEnumConverter))]
public enum ButtonType
{
    [EnumMember(Value = "button_a")]
    ButtonA,
    [EnumMember(Value = "button_b")]
    ButtonB
}

Notice the JsonConverter notation.

here http://james.newtonking.com/json/help/index.html you can see also that info.

Hope it helps you out.

All 4 comments

@ikaman can you give an example of the JSON you want to deserialize?

Yes ofcourse. I should have done this from the start

Check out this piece of code:

[DataContract]
public class Test
{
    [DataMember(Name = "button_type")]
    public ButtonType ButtonType { get; set; }
}

[DataContract]
public enum ButtonType
{
    [EnumMember(Value = "button_a")]
    ButtonA,

    [EnumMember(Value = "button_b")]
    ButtonB
}

class Program
{
    static void Main(string[] args)
    {
        var a1 = "{ \"button_type\" :  \"button_a\"}";
        var a2 = "{ \"button_type\" :  \"buttonA\"}";

        var ra1 = Deserialize(a1);
        var ra2 = Deserialize(a2);
    }

    private static Test Deserialize(string text)
    {
        var serializer = new JsonSerializer();

        try
        {
            using (var stringReader = new StringReader(text))
            using (var jsonReader = new JsonTextReader(stringReader))
                return serializer.Deserialize<Test>(jsonReader);
        }
        catch (Exception e)
        {
            return null;
        }
    }
}

for ra1 you will get null (serialization failed) while for ra2 you will get the right enum.

So even though in json ButtonType is called button_type it will deserialize it correctly (because of [DataMember(Name = "button_type")] attribute).

For enums it doesn't work like that. I've tried with various attributes but in the end realized it doesn't matter because internally json.net uses enum.tryparse which probably doesn't care about any of those attributes.

so
1) Is there some kind of attribute that could be applied to an enum so that I could deserialize enum to a different value then the json string (very useful when working with ruby guys as their naming convention is different then c#'s)
2) if there isn't is this a bug or possibly a new feature request?

Thanks in advance

After checking the code and doing some research the best option you have is to set your enum like this:

[DataContract]
[JsonConverter(typeof(StringEnumConverter))]
public enum ButtonType
{
    [EnumMember(Value = "button_a")]
    ButtonA,
    [EnumMember(Value = "button_b")]
    ButtonB
}

Notice the JsonConverter notation.

here http://james.newtonking.com/json/help/index.html you can see also that info.

Hope it helps you out.

Great this fixed my issue.

Thank you very much for this info!

Was this page helpful?
0 / 5 - 0 ratings