c# - 带下划线的 MVC 3 模型绑定(bind)

标签 c# asp.net-mvc json asp.net-mvc-3 model-binding

我正在发布带有下划线变量名称的 json (like_this) 并尝试绑定(bind)到驼峰式 (LikeThis) 的模型,但值无法绑定(bind)被束缚。

我知道我可以编写自定义模型联编程序,但由于带下划线的约定非常普遍,我希望已经存在解决方案。

我要发布的 Action /模型是:

/* in controller */
[HttpPost]
public ActionResult UpdateArgLevel(UserArgLevelModel model) {
    // do something with the data
}

/* model */
public class UserArgLevelModel {
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string Surname { get; set; }
    public int ArgLevelId { get; set; }
}

json 数据如下:

{
    id: 420007,
    first_name: "Marc",
    surname: "Priddes",
    arg_level_id: 4
}

(不幸的是,我无法更改 json 或模型的命名)

最佳答案

你可以开始写一个 custom Json.NET 契约(Contract)解析器:

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());
    }
}

这是针对您的特定情况,因为您需要 snake case 契约(Contract)解析器:

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

然后你可以写一个自定义属性来装饰你的 Controller Action :

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;
        }
    }
}

最后:

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

关于c# - 带下划线的 MVC 3 模型绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11613253/

相关文章:

c# - 对象名称 'dbo.UserNotes' 无效。异常 - ASP.NET MVC 4

javascript - 向 ASP MVC 结果注入(inject)一些内容

javascript - 迭代 JSON 对象

python - 将 json 数据转换为数据框

c# - 在 ASP.NET MVC 应用程序中放置函数

c# - 通过 C# 将 JSON 数据 POST 到 PHP 并将值存储在 MYSQL 中

c# - 使用naudio录制特定的应用程序音频

c# - Linq to Xml 查询子节点

c# - 如何将 Iron ruby​​ 嵌入到 C# 程序中?

asp.net - Azure Blob 存储有开源文件夹/浏览器/创建器吗?