<PackageReference Include="Newtonsoft.Json" Version="6.0.5" />

StringEnumConverter

Converts an Enum to and from its name string value.
using Newtonsoft.Json.Utilities; using System; using System.Globalization; using System.Linq; using System.Reflection; using System.Runtime.Serialization; namespace Newtonsoft.Json.Converters { public class StringEnumConverter : JsonConverter { private static readonly ThreadSafeStore<Type, BidirectionalDictionary<string, string>> EnumMemberNamesPerType = new ThreadSafeStore<Type, BidirectionalDictionary<string, string>>(InitializeEnumType); public bool CamelCaseText { get; set; } public bool AllowIntegerValues { get; set; } public StringEnumConverter() { AllowIntegerValues = true; } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { if (value == null) writer.WriteNull(); else { Enum enum = (Enum)value; string text = enum.ToString("G"); if (char.IsNumber(text[0]) || text[0] == '-') writer.WriteValue(value); else { BidirectionalDictionary<string, string> bidirectionalDictionary = EnumMemberNamesPerType.Get(enum.GetType()); string[] array = text.Split(new char[1] { ',' }); for (int i = 0; i < array.Length; i++) { string text2 = array[i].Trim(); bidirectionalDictionary.TryGetByFirst(text2, out string second); second = (second ?? text2); if (CamelCaseText) second = StringUtils.ToCamelCase(second); array[i] = second; } string value2 = string.Join(", ", array); writer.WriteValue(value2); } } } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { bool flag = ReflectionUtils.IsNullableType(objectType); Type type = flag ? Nullable.GetUnderlyingType(objectType) : objectType; if (reader.TokenType == JsonToken.Null) { if (!ReflectionUtils.IsNullableType(objectType)) throw JsonSerializationException.Create(reader, "Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType)); return null; } try { if (reader.TokenType == JsonToken.String) { string text = reader.Value.ToString(); if (text == string.Empty && flag) return null; BidirectionalDictionary<string, string> map = EnumMemberNamesPerType.Get(type); string value; if (text.IndexOf(',') != -1) { string[] array = text.Split(new char[1] { ',' }); for (int i = 0; i < array.Length; i++) { string enumText = array[i].Trim(); array[i] = ResolvedEnumName(map, enumText); } value = string.Join(", ", array); } else value = ResolvedEnumName(map, text); return Enum.Parse(type, value, true); } if (reader.TokenType == JsonToken.Integer) { if (!AllowIntegerValues) throw JsonSerializationException.Create(reader, "Integer value {0} is not allowed.".FormatWith(CultureInfo.InvariantCulture, reader.Value)); return ConvertUtils.ConvertOrCast(reader.Value, CultureInfo.InvariantCulture, type); } } catch (Exception ex) { throw JsonSerializationException.Create(reader, "Error converting value {0} to type '{1}'.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.FormatValueForPrint(reader.Value), objectType), ex); } throw JsonSerializationException.Create(reader, "Unexpected token {0} when parsing enum.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); } private static string ResolvedEnumName(BidirectionalDictionary<string, string> map, string enumText) { map.TryGetBySecond(enumText, out string first); first = (first ?? enumText); return first; } public override bool CanConvert(Type objectType) { Type type = ReflectionUtils.IsNullableType(objectType) ? Nullable.GetUnderlyingType(objectType) : objectType; return type.IsEnum(); } private static BidirectionalDictionary<string, string> InitializeEnumType(Type type) { BidirectionalDictionary<string, string> bidirectionalDictionary = new BidirectionalDictionary<string, string>(StringComparer.OrdinalIgnoreCase, StringComparer.OrdinalIgnoreCase); foreach (FieldInfo field in TypeExtensions.GetFields(type)) { string name = field.Name; string text = (from EnumMemberAttribute a in CustomAttributeExtensions.GetCustomAttributes(field, typeof(EnumMemberAttribute), true) select a.Value).SingleOrDefault() ?? field.Name; if (bidirectionalDictionary.TryGetBySecond(text, out string _)) throw new InvalidOperationException("Enum name '{0}' already exists on enum '{1}'.".FormatWith(CultureInfo.InvariantCulture, text, type.get_Name())); bidirectionalDictionary.Set(name, text); } return bidirectionalDictionary; } } }