StringEnumConverter
Converts an  Enum to and from its name string value.
            
                using Newtonsoft.Json.Serialization;
using Newtonsoft.Json.Utilities;
using System;
using System.Globalization;
using System.Runtime.CompilerServices;
namespace Newtonsoft.Json.Converters
{
    [System.Runtime.CompilerServices.NullableContext(1)]
    [System.Runtime.CompilerServices.Nullable(0)]
    public class StringEnumConverter : JsonConverter
    {
        [Obsolete("StringEnumConverter.CamelCaseText is obsolete. Set StringEnumConverter.NamingStrategy with CamelCaseNamingStrategy instead.")]
        public bool CamelCaseText {
            get {
                if (!(NamingStrategy is CamelCaseNamingStrategy))
                    return false;
                return true;
            }
            set {
                if (value) {
                    if (!(NamingStrategy is CamelCaseNamingStrategy))
                        NamingStrategy = new CamelCaseNamingStrategy();
                } else if (NamingStrategy is CamelCaseNamingStrategy) {
                    NamingStrategy = null;
                }
            }
        }
        [System.Runtime.CompilerServices.Nullable(2)]
        [field: System.Runtime.CompilerServices.Nullable(2)]
        public NamingStrategy NamingStrategy {
            [System.Runtime.CompilerServices.NullableContext(2)]
            get;
            [System.Runtime.CompilerServices.NullableContext(2)]
            set;
        }
        public bool AllowIntegerValues { get; set; } = true;
        public StringEnumConverter()
        {
        }
        [Obsolete("StringEnumConverter(bool) is obsolete. Create a converter with StringEnumConverter(NamingStrategy, bool) instead.")]
        public StringEnumConverter(bool camelCaseText)
        {
            if (camelCaseText)
                NamingStrategy = new CamelCaseNamingStrategy();
        }
        public StringEnumConverter(NamingStrategy namingStrategy, bool allowIntegerValues = true)
        {
            NamingStrategy = namingStrategy;
            AllowIntegerValues = allowIntegerValues;
        }
        public StringEnumConverter(Type namingStrategyType)
        {
            ValidationUtils.ArgumentNotNull(namingStrategyType, "namingStrategyType");
            NamingStrategy = JsonTypeReflector.CreateNamingStrategyInstance(namingStrategyType, null);
        }
        public StringEnumConverter(Type namingStrategyType, object[] namingStrategyParameters)
        {
            ValidationUtils.ArgumentNotNull(namingStrategyType, "namingStrategyType");
            NamingStrategy = JsonTypeReflector.CreateNamingStrategyInstance(namingStrategyType, namingStrategyParameters);
        }
        public StringEnumConverter(Type namingStrategyType, object[] namingStrategyParameters, bool allowIntegerValues)
        {
            ValidationUtils.ArgumentNotNull(namingStrategyType, "namingStrategyType");
            NamingStrategy = JsonTypeReflector.CreateNamingStrategyInstance(namingStrategyType, namingStrategyParameters);
            AllowIntegerValues = allowIntegerValues;
        }
        public override void WriteJson(JsonWriter writer, [System.Runtime.CompilerServices.Nullable(2)] object value, JsonSerializer serializer)
        {
            if (value == null)
                writer.WriteNull();
            else {
                Enum enum = (Enum)value;
                if (!EnumUtils.TryToString(enum.GetType(), value, NamingStrategy, out string name)) {
                    if (!AllowIntegerValues)
                        throw JsonSerializationException.Create(null, writer.ContainerPath, "Integer value {0} is not allowed.".FormatWith(CultureInfo.InvariantCulture, enum.ToString("D")), null);
                    writer.WriteValue(value);
                } else
                    writer.WriteValue(name);
            }
        }
        [return: System.Runtime.CompilerServices.Nullable(2)]
        public override object ReadJson(JsonReader reader, Type objectType, [System.Runtime.CompilerServices.Nullable(2)] object existingValue, JsonSerializer serializer)
        {
            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;
            }
            bool flag = ReflectionUtils.IsNullableType(objectType);
            Type type = flag ? Nullable.GetUnderlyingType(objectType) : objectType;
            try {
                if (reader.TokenType == JsonToken.String) {
                    string value = reader.Value?.ToString();
                    if (!(StringUtils.IsNullOrEmpty(value) & flag))
                        return EnumUtils.ParseEnum(type, NamingStrategy, value, !AllowIntegerValues);
                    return null;
                }
                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.ToString(reader.Value), objectType), ex);
            }
            throw JsonSerializationException.Create(reader, "Unexpected token {0} when parsing enum.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
        }
        public override bool CanConvert(Type objectType)
        {
            return (ReflectionUtils.IsNullableType(objectType) ? Nullable.GetUnderlyingType(objectType) : objectType).IsEnum();
        }
    }
}