MVC 3 model binding with underscores MVC 3 model binding with underscores json json

MVC 3 model binding with underscores


You can start writing a custom Json.NET ContractResolver:

public class DeliminatorSeparatedPropertyNamesContractResolver :    DefaultContractResolver{    private readonly string _separator;    protected DeliminatorSeparatedPropertyNamesContractResolver(char separator)        : base(true)    {        _separator = separator.ToString();    }    protected override string ResolvePropertyName(string propertyName)    {        var parts = new List<string>();        var currentWord = new StringBuilder();        foreach (var c in propertyName)        {            if (char.IsUpper(c) && currentWord.Length > 0)            {                parts.Add(currentWord.ToString());                currentWord.Clear();            }            currentWord.Append(char.ToLower(c));        }        if (currentWord.Length > 0)        {            parts.Add(currentWord.ToString());        }        return string.Join(_separator, parts.ToArray());    }}

This is for your particular case, becase you need a snake case ContractResolver:

public class SnakeCasePropertyNamesContractResolver :    DeliminatorSeparatedPropertyNamesContractResolver{    public SnakeCasePropertyNamesContractResolver() : base('_') { }}

Then you can write a custom attribute to decorate your controller actions:

public class JsonFilterAttribute : ActionFilterAttribute{    public string Parameter { get; set; }    public Type JsonDataType { get; set; }    public JsonSerializerSettings Settings { get; set; }    public override void OnActionExecuting(ActionExecutingContext filterContext)    {            if (filterContext.HttpContext.Request.ContentType.Contains("application/json"))        {            string inputContent;            using (var reader = new StreamReader(filterContext.HttpContext.Request.InputStream))            {                inputContent = reader.ReadToEnd();            }            var result = JsonConvert.DeserializeObject(inputContent, JsonDataType, Settings ?? new JsonSerializerSettings());            filterContext.ActionParameters[Parameter] = result;        }    }}

And finally:

[JsonFilter(Parameter = "model", JsonDataType = typeof(UserArgLevelModel), Settings = new JsonSerializerSettings { ContractResolver = new SnakeCasePropertyNamesContractResolver() })]public ActionResult UpdateArgLevel(UserArgLevelModel model) {{    // model is deserialized correctly!}