using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters;
using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
public class StringEnumContractResolver : DefaultContractResolver
readonly StringEnumConverter converter;
public StringEnumContractResolver() : this(true, false) { }
public StringEnumContractResolver(bool allowIntegerValue, bool camelCaseText)
this.converter = new StringEnumConverter { AllowIntegerValues = allowIntegerValue, CamelCaseText = camelCaseText };
protected override JsonPrimitiveContract CreatePrimitiveContract(Type objectType)
var contract = base.CreatePrimitiveContract(objectType);
var type = Nullable.GetUnderlyingType(contract.UnderlyingType) ?? contract.UnderlyingType;
if (type.IsEnum && contract.Converter == null)
contract.Converter = converter;
public enum IntEnum : int
public enum ByteEnum : byte
public enum ULongEnum : ulong
Fourteen = ((ulong)1 << 14),
ThirtyOne = ((ulong)1 << 31),
ThirtyTwo = ((ulong)1 << 32),
ThirtyThree = ((ulong)1 << 33),
Sixty = ((ulong)1 << 60),
SixtyOne = ((ulong)1 << 61),
SixtyTwo = ((ulong)1 << 62),
SixtyThree = ((ulong)1 << 63),
public enum UnflaggedLongEnum : long
Fourteen = ((long)1 << 14),
ThirtyOne = ((long)1 << 31),
ThirtyTwo = ((long)1 << 32),
SixtyTwo = ((long)1 << 62),
SixtyThree = ((long)1 << 63),
public enum UnflaggedULongEnum : ulong
Fourteen = ((ulong)1 << 14),
ThirtyOne = ((ulong)1 << 31),
ThirtyTwo = ((ulong)1 << 32),
ThirtyThree = ((ulong)1 << 33),
Sixty = ((ulong)1 << 60),
SixtyOne = ((ulong)1 << 61),
SixtyTwo = ((ulong)1 << 62),
SixtyThree = ((ulong)1 << 63),
public enum CompositeExample : ulong
public class RootObject<TEnum>
this.List = new List<TEnum>();
this.Dictionary = new Dictionary<TEnum, string>();
public TEnum Property { get; set; }
public object UntypedProperty { get; set; }
public List<TEnum> List { get; set; }
public Dictionary<TEnum, string> Dictionary { get; set; }
public static void Test()
Test<UnflaggedULongEnum>();
Test<IntEnum>(new[] { IntEnum.Fourteen, (IntEnum)(-1), IntEnum.Two, IntEnum.Seven | IntEnum.One | IntEnum.Two });
Test<CompositeExample>();
Console.WriteLine("\nDone.");
static void Test<TEnum>() where TEnum : struct, IComparable
Console.WriteLine(string.Format("\nTesting {0}", typeof(TEnum)));
Test(Enum.GetValues(typeof(TEnum)).Cast<TEnum>());
Test(Enum.GetValues(typeof(TEnum)).Cast<TEnum>().Select(e => (TEnum?)e).Concat(new[] { (TEnum?)null }));
public static void Test<TEnum>(IEnumerable<TEnum> values)
var root = new RootObject<TEnum>
Property = values.FirstOrDefault(),
UntypedProperty = values.LastOrDefault(),
Dictionary = values.Distinct().Where(v => v != null).ToDictionary(v => v, v => "hello " + v.ToString()),
var settings = new JsonSerializerSettings
ContractResolver = new StringEnumContractResolver(),
var json = JsonConvert.SerializeObject(root, Formatting.Indented, settings);
public static void Main()
Console.WriteLine("Environment version: " + Environment.Version);
Console.WriteLine("Json.NET version: " + typeof(JsonSerializer).Assembly.FullName);
Console.WriteLine("Failed with unhandled exception: ");
public class AssertionFailedException : System.Exception
public AssertionFailedException() : base() { }
public AssertionFailedException(string s) : base(s) { }
public static class Assert
public static void IsTrue(bool value)
public static void IsTrue(bool value, string message)
throw new AssertionFailedException(message ?? "failed");