8

I have an enum:

public enum IdleDelayBreakMode
{
    Repeat,
    ShowNext
}

I'm using NewtonSoft.Json to convert to json objects containing properties of that enum's type. What's the best solution to serialize values of that enum to arbitrary integers? Ideally i would like to do something like on the snippet below and i want to know if maybe there's a built-in solution for that:

public enum IdleDelayBreakMode
{
    [JsonValue(100)]
    Repeat,             // When serializing will be converted to 100

    [JsonValue(200)]
    ShowNext            // When serializing will be converted to 200  
}
Mariusz Jamro
  • 30,615
  • 24
  • 120
  • 162
  • What if you just set their values? `Repeat = 100` and `ShowNext = 200`. – juharr Jul 14 '16 at 19:05
  • You want to serialize the enum to different integers than how the enum is defined? – Mike Zboray Jul 14 '16 at 19:06
  • You need to create a class that inherits from JsonConverter, then apply this attribute to your enum [JsonConverter(typeof(MyConverter))] – Jon Jul 14 '16 at 19:07

3 Answers3

11

You can just set enum values like that:

public enum IdleDelayBreakMode
{
    Repeat = 100,
    ShowNext = 200
}

Newtonsoft.Json will use enum values. There is no need to set attributes. This way it will be consistent across the system whether you need to serialize it to JSON, save it in the database using Entity Framework etc.


Are you using your enum as integer constants storage?

In this case you might want to inherit it from int:

public enum IdleDelayBreakMode : int
Andrei
  • 42,814
  • 35
  • 154
  • 218
6

Assuming you don't want to modify the underlying enum values (as is shown in the other answers), you can decorate your enum vales with [EnumMember(Value = "Name")] attributes and use the alternate numeric values as the name strings:

[JsonConverter(typeof(StringEnumConverter))]
[DataContract]
public enum IdleDelayBreakMode
{
    [EnumMember(Value = "100")]
    Repeat,
    [EnumMember(Value = "200")]
    ShowNext
}

You will also need to serialize using StringEnumConverter, either by adding [JsonConverter(typeof(StringEnumConverter))] directly to the enum or by applying it globally according to this answer.

This works with [Flags] as well. Serializing both values of the following:

[Flags]
[DataContract]
[JsonConverter(typeof(StringEnumConverter))]
public enum IdleDelayBreakModeFlags
{
    [EnumMember(Value = "100")]
    Repeat = (1 << 0),
    [EnumMember(Value = "200")]
    ShowNext = (1 << 1),
}

produces "100, 200".

Adding these attributes will cause DataContractSerializer as well as Json.NET to use these alternate name strings. If you would prefer not to affect the behavior of the data contract serializer, remove [DataContract] but keep the [EnumMember] attributes.

dbc
  • 104,963
  • 20
  • 228
  • 340
5

Just set the integer values in your enum items directly instead of using an attribute:

public enum IdleDelayBreakMode
{
    Repeat = 100,
    ShowNext = 200
}

JSON.Net will them use the integer values when serializing/deserializing a property of type IdleDelayBreakMode

Pedro
  • 2,300
  • 1
  • 18
  • 22