Created
September 5, 2018 15:31
-
-
Save thoemmi/4cf462690537c2e3042247f265c17e97 to your computer and use it in GitHub Desktop.
JSON Converter for enum flags
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class EnumFlagsConverter : JsonConverter | |
{ | |
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) | |
{ | |
var x = ((Enum) value).ToString(); | |
var list = new List<string>(); | |
foreach (var v in x.Split(new[] {", "}, StringSplitOptions.RemoveEmptyEntries)) | |
{ | |
list.Add(v); | |
} | |
if (list.Count == 1) | |
{ | |
writer.WriteValue(list[0]); | |
} | |
else | |
{ | |
serializer.Serialize(writer, list); | |
} | |
} | |
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, | |
JsonSerializer serializer) | |
{ | |
object result = null; | |
if (reader.TokenType == JsonToken.String) | |
{ | |
result = Enum.Parse(objectType, (string) reader.Value, ignoreCase: true); | |
} | |
else if (reader.TokenType == JsonToken.StartArray) | |
{ | |
var values = serializer.Deserialize<string[]>(reader); | |
result = values | |
.Select(t => (int) Enum.Parse(objectType, t, ignoreCase: true)) | |
.Aggregate((t, a) => a | t); | |
} | |
return result; | |
} | |
public override bool CanConvert(Type objectType) | |
{ | |
return objectType.IsEnum && objectType.GetCustomAttribute<FlagsAttribute>() != null; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class EnumFlagsConverterTests | |
{ | |
public EnumFlagsConverterTests() | |
{ | |
JsonConvert.DefaultSettings = () => new JsonSerializerSettings | |
{ | |
Converters = new List<JsonConverter> {new EnumFlagsConverter()} | |
}; | |
} | |
[Flags] | |
public enum TestEnum | |
{ | |
Zero = 0, | |
One = 1, | |
Two = 2, | |
Four = 4, | |
All = 7 | |
} | |
public class TestClass | |
{ | |
public TestEnum Test { get; set; } | |
} | |
[Fact] | |
public void can_serialize_enum_zero() | |
{ | |
var value = TestEnum.Zero; | |
var result = JsonConvert.SerializeObject(value); | |
Assert.Equal("\"Zero\"", result); | |
} | |
[Fact] | |
public void can_serialize_enum_one() | |
{ | |
var value = TestEnum.One; | |
var result = JsonConvert.SerializeObject(value); | |
Assert.Equal("\"One\"", result); | |
} | |
[Fact] | |
public void can_serialize_enum_one_or_two() | |
{ | |
var value = TestEnum.One | TestEnum.Two; | |
var result = JsonConvert.SerializeObject(value); | |
Assert.Equal("[\"One\",\"Two\"]", result); | |
} | |
[Fact] | |
public void can_serialize_enum_one_or_two_or_four() | |
{ | |
var value = TestEnum.One | TestEnum.Two | TestEnum.Four; | |
var result = JsonConvert.SerializeObject(value); | |
Assert.Equal("\"All\"", result); | |
} | |
[Fact] | |
public void can_serialize_enum_all() | |
{ | |
var value = TestEnum.All; | |
var result = JsonConvert.SerializeObject(value); | |
Assert.Equal("\"All\"", result); | |
} | |
[Fact] | |
public void can_serialize_enum_one_and_all() | |
{ | |
var value = TestEnum.One | TestEnum.All; | |
var result = JsonConvert.SerializeObject(value); | |
Assert.Equal("\"All\"", result); | |
} | |
[Fact] | |
public void can_serialize_member() | |
{ | |
var testClass = new TestClass | |
{ | |
Test = TestEnum.One | TestEnum.Four | |
}; | |
var result = JsonConvert.SerializeObject(testClass); | |
Assert.Equal("{\"Test\":[\"One\",\"Four\"]}", result); | |
} | |
[Fact] | |
public void can_deserialize_enum_zero() | |
{ | |
var result = JsonConvert.DeserializeObject<TestEnum>("\"Zero\""); | |
Assert.Equal(TestEnum.Zero, result); | |
} | |
[Fact] | |
public void can_deserialize_enum_one() | |
{ | |
var result = JsonConvert.DeserializeObject<TestEnum>("\"One\""); | |
Assert.Equal(TestEnum.One, result); | |
} | |
[Fact] | |
public void can_deserialize_enum_one_lowercase() | |
{ | |
var result = JsonConvert.DeserializeObject<TestEnum>("\"one\""); | |
Assert.Equal(TestEnum.One, result); | |
} | |
[Fact] | |
public void can_deserialize_enum_one_or_two() | |
{ | |
var result = JsonConvert.DeserializeObject<TestEnum>("[\"One\",\"Two\"]"); | |
Assert.Equal(TestEnum.One | TestEnum.Two, result); | |
} | |
[Fact] | |
public void can_deserialize_enum_one_or_two_or_four() | |
{ | |
var result = JsonConvert.DeserializeObject<TestEnum>("[\"One\",\"Two\",\"Four\"]"); | |
Assert.Equal(TestEnum.All, result); | |
} | |
[Fact] | |
public void can_deserialize_enum_all() | |
{ | |
var result = JsonConvert.DeserializeObject<TestEnum>("\"All\""); | |
Assert.Equal(TestEnum.All, result); | |
} | |
[Fact] | |
public void can_deserialize_enum_one_and_all() | |
{ | |
var result = JsonConvert.DeserializeObject<TestEnum>("[\"One\",\"All\"]"); | |
Assert.Equal(TestEnum.All, result); | |
} | |
[Fact] | |
public void can_deserialize_member() | |
{ | |
var testClass = new TestClass | |
{ | |
Test = TestEnum.Two | TestEnum.Four | |
}; | |
var result = JsonConvert.DeserializeObject<TestClass>("{\"Test\":[\"Two\",\"Four\"]}"); | |
result.Should().BeEquivalentTo(testClass); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment