Skip to content

Instantly share code, notes, and snippets.

@danielcrenna
Created October 21, 2015 16:14
Show Gist options
  • Save danielcrenna/f57bd99d5702bf10013f to your computer and use it in GitHub Desktop.
Save danielcrenna/f57bd99d5702bf10013f to your computer and use it in GitHub Desktop.
JSON.NET polyfill
/// <summary>
/// Handles casing, as well as conventionally deserializes to any interfaces rather than the full type
/// License: https://opensource.org/licenses/MIT
/// </summary>
public class JsonContractResolver : DefaultContractResolver
{
private readonly Case _case;
public enum Case
{
Pascal,
Camel,
Snake
}
public JsonContractResolver(Case @case)
{
_case = @case;
}
public class ToStringComparer : IComparer
{
public int Compare(object x, object y)
{
return string.Compare(x.ToString(), y.ToString(), StringComparison.Ordinal);
}
}
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
IList<JsonProperty> properties = new List<JsonProperty>();
var interfaces = type.GetInterfaces();
if (interfaces == null || interfaces.Length == 0)
properties = base.CreateProperties(type, memberSerialization);
else
{
foreach (var interfaceType in interfaces)
{
var props = base.CreateProperties(interfaceType, memberSerialization);
foreach (var prop in props)
{
if (!properties.Contains(prop))
properties.Add(prop);
}
}
}
return properties;
}
protected override string ResolvePropertyName(string propertyName)
{
switch (_case)
{
case Case.Camel:
return ToCamelCase(propertyName);
case Case.Snake:
return ToSnakeCase(propertyName);
default:
return base.ResolvePropertyName(propertyName);
}
}
private static string ToCamelCase(string s)
{
if (string.IsNullOrEmpty(s) || !char.IsUpper(s[0]))
return s;
char[] chArray = s.ToCharArray();
for (int index = 0; index < chArray.Length; ++index)
{
bool flag = index + 1 < chArray.Length;
if (index <= 0 || !flag || char.IsUpper(chArray[index + 1]))
chArray[index] = char.ToLowerInvariant(chArray[index]);
else
break;
}
return new string(chArray);
}
private static string ToSnakeCase(string input)
{
if (input.Length > 0 && char.IsLower(input[0]))
{
return input;
}
if (string.IsNullOrEmpty(input))
{
return null;
}
var result = new StringBuilder();
result.Append(char.ToLowerInvariant(input[0]));
for (var i = 1; i < input.Length; i++)
{
if (char.IsLower(input[i]))
{
result.Append(input[i]);
}
else
{
result.Append("_");
result.Append(char.ToLowerInvariant(input[i]));
}
}
return result.ToString();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment