首页 > 解决方案 > ASP.NET Core MVC 模型绑定错误?

问题描述

我在使用 ASP.NET Core 的模型绑定时遇到了一些问题。基本上我只是想将一些 POSTed json 绑定到具有嵌套属性的对象模型。下面为单个按钮提供了最少的代码,当按下该按钮时,它将通过 XMLHttpRequest POST 到控制器操作方法。action 方法采用带有[FromBody]属性的单个模型类参数。

模型:

public class OuterModel {
    public string OuterString { get; set; }
    public int OuterInt { get; set; }
    public InnerModel Inner { get; set; }
}

public class InnerModel {
    public string InnerString { get; set; }
    public int InnerInt { get; set; }
}

控制器:

using Microsoft.AspNetCore.Mvc;

public class HomeController : Controller {

    [HttpPost("models/")]
    public IActionResult Save([FromBody] OuterModel viewModel) {
        if (!ModelState.IsValid)
            return BadRequest(ModelState);

        // Return an appropriate response
        return Ok();
    }
}

“提交”按钮的 Razor 标记:

<div class="form-row">
    <div class="col-2">
        @{ string url = Url.Action(nameof(HomeController.Save), "Home"); }
        <button id="post-btn" data-post-url="@url">POST</button>
    </div>
</div>

要提交的 JavaScript(不绑定):

document.getElementById("post-btn").addEventListener("click", e => {
        const xhr = new XMLHttpRequest();
        xhr.addEventListener("timeout", () => console.error("Timeout"));
        xhr.addEventListener("error", () => console.error("Error"));
        xhr.addEventListener("load", () => console.log(`Status: ${xhr.status} ${xhr.statusText}`));
        xhr.open("POST", e.target.dataset.postUrl);
        xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
        xhr.send(JSON.stringify({
            "OuterString": "outer",
            "OuterInt": 1,
            "Inner.InnerString": "inner",
            "Inner.InnerInt": 5
        }));
    });

看看那个 JavaScript,我希望Inner.*json 属性名称能够正确绑定,给定文档中的这一行:

模型绑定查找模式parameter_name.property_name以将值绑定到属性。如果它没有找到此表单的匹配值,它将尝试仅使用属性名称进行绑定。

但事实并非如此;action 方法中的OuterModel.Inner属性结束了null。但是,以下 json确实正确绑定:

JavaScript 提交(绑定):

xhr.send(JSON.stringify({
    "OuterString": "outer",
    "OuterInt": 1,
    "Inner": {
        "InnerString": "inner",
        "InnerInt": 5
    }
}));

所以我可以使用这段代码来实现我需要的模型绑定,我只是对为什么第一个 JavaScript不起作用感到困惑。我没有为嵌套属性使用正确的命名约定吗?一些澄清将不胜感激!

标签: c#asp.net-coreasp.net-core-mvcmodel-binding

解决方案


推荐阅读