Json.NET custom serialization of a enum type with data annotation
Ok, this can probably be cleaned up a bit, but I would write two custom converters: one for the Enum
type, and another for the enum value:
I created a custom class to serialize into the end result that you want:
public class EnumValue
{
public int Value { get; set; }
public string Name { get; set; }
public string Label { get; set; }
}
As well as a static class that does some of the legwork for creating instances of that type from Enum
s and enum values:
public static class EnumHelpers
{
public static EnumValue GetEnumValue(object value, Type enumType)
{
MemberInfo member = enumType.GetMember(value.ToString())[0];
DisplayAttribute attribute =
member.GetCustomAttribute<DisplayAttribute>();
return new EnumValue
{
Value = (int)value,
Name = Enum.GetName(enumType, value),
Label = attribute.Name
};
}
public static EnumValue[] GetEnumValues(Type enumType)
{
Array values = Enum.GetValues(enumType);
EnumValue[] result = new EnumValue[values.Length];
for (int i = 0; i < values.Length; i++)
{
result[i] = GetEnumValue(
values.GetValue(i),
enumType);
}
return result;
}
}
Then there are two converter classes. This first one serializes System.Type
into the object you wanted:
public class EnumTypeConverter : JsonConverter
{
public override void WriteJson(
JsonWriter writer,
object value,
JsonSerializer serializer)
{
if (value == null)
{
writer.WriteNull();
return;
}
EnumValue[] values = EnumHelpers.GetEnumValues((Type)value);
serializer.Serialize(writer, values);
}
public override object ReadJson(
JsonReader reader,
Type objectType,
object existingValue,
JsonSerializer serializer)
{
throw new NotSupportedException();
}
public override bool CanRead { get { return false; } }
public override bool CanConvert(Type objectType)
{
return typeof(Type).IsAssignableFrom(objectType);
}
}
And then there's the one that serializes the actual enum value:
public class EnumValueConverter : JsonConverter
{
public override void WriteJson(
JsonWriter writer,
object value,
JsonSerializer serializer)
{
if (value == null)
{
writer.WriteNull();
return;
}
EnumValue result = EnumHelpers.GetEnumValue(value, value.GetType());
serializer.Serialize(writer, result);
}
public override object ReadJson(
JsonReader reader,
Type objectType,
object existingValue,
JsonSerializer serializer)
{
throw new NotSupportedException();
}
public override bool CanRead { get { return false; } }
public override bool CanConvert(Type objectType)
{
return objectType.IsEnum;
}
}
Here's how you would use all of it:
var pr = new ProjectDto();
pr.CurrentStatus = Status.Active;
pr.StatusEnum = typeof(Status);
var settings = new JsonSerializerSettings();
settings.Converters = new JsonConverter[]
{
new EnumTypeConverter(),
new EnumValueConverter()
};
settings.Formatting = Newtonsoft.Json.Formatting.Indented;
string serialized = JsonConvert.SerializeObject(pr, settings);
Example: https://dotnetfiddle.net/BVp7a2