using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
public static void Main()
""full_name"": ""John Smith"",
var inputDto = JsonConvert.DeserializeObject<InputObjectDTO>(
new JsonSerializerSettings { ContractResolver = new SnakeCaseContractResolver() }
Console.WriteLine( "{0}: {1}", inputDto.FullName, inputDto.TotalPrice );
public class InputObjectDTO {
public string FullName { get; set; }
public int TotalPrice { get; set; }
[AttributeUsage(AttributeTargets.Class)]
public class SnakeCasedAttribute : Attribute {
public SnakeCasedAttribute() {
public class SnakeCaseConverter : JsonConverter {
public override bool CanConvert(Type objectType) {
return objectType.GetCustomAttributes(true).OfType<SnakeCasedAttribute>().Any() == true;
private static string ConvertFromSnakeCase(string snakeCased) {
return string.Join("", snakeCased.Split('_').Select(part => part.Substring(0, 1).ToUpper() + part.Substring(1)));
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
var target = Activator.CreateInstance( objectType );
var jobject = JObject.Load(reader);
foreach (var property in jobject.Properties()) {
var propName = ConvertFromSnakeCase(property.Name);
var prop = objectType.GetProperty(propName);
if (prop == null || !prop.CanWrite) {
prop.SetValue(target, property.Value.ToObject(prop.PropertyType, serializer));
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
throw new NotImplementedException();
public class SnakeCaseContractResolver : DefaultContractResolver {
public static readonly SnakeCaseContractResolver Instance = new SnakeCaseContractResolver();
protected override JsonContract CreateContract(Type objectType) {
JsonContract contract = base.CreateContract(objectType);
if ( objectType.GetCustomAttributes(true).OfType<SnakeCasedAttribute>().Any() ) {
contract.Converter = new SnakeCaseConverter();