Created
October 21, 2015 16:14
-
-
Save danielcrenna/f57bd99d5702bf10013f to your computer and use it in GitHub Desktop.
JSON.NET polyfill
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <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