如何在控制器中将发布参数绑定到动作参数?

时间:2019-06-15 10:46:55

标签: javascript asp.net-core

动作是这样的:

[AllowAnonymous]
[HttpPost]
public async Task<IActionResult> Update(int id, string userName, string firstName, string lastName, string email, string role, string returnUrl = null)
{ 
    ...
}

当我调试应用程序时,即使方法中的参数不为空,参数在方法的主体中始终为空。

0%5Bid%5D=10&1%5BuserName%5D=Mike99&2%5BfirstName%5D=Mike&3%5BlastName%5D=Johnson&4%5Bemail%5D=mike.johnson%40live.com&5%5Brole%5D=user

http post

路由配置:

app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "default",
        template: "{controller=Home}/{action=Index}/{id?}");
    });
};

请求是由Ajax提出的:

$.post("/Users/Update", postData)
    .done(function (data) {
        row.find(".changed").attr('class', 'editable');
        dataTable.draw();
    });

当我用Postman击中动作时,它似乎获得了正确的数据,只是不喜欢jQuery发送的数据。

问题就变成了:如何正确格式化AJAX发送的数据?

邮递员发送的数据:

id=10&userName=Mike99&firstName=Mike&lastName=Johnson&email=mike.johnson%40mail.com&role=user

将其与AJAX发送的数据进行对比:

0%5Bid%5D=10&1%5BuserName%5D=Mike99&2%5BfirstName%5D=Mike&3%5BlastName%5D=Johnson&4%5Bemail%5D=mike.johnson%40live.com&5%5Brole%5D=user

postData在使用console.log(postData)时如下所示:

{0: {…}, 1: {…}, 2: {…}, 3: {…}, 4: {…}, 5: {…}}
0: {id: 10}
1: {userName: "Mike99"}
2: {firstName: "Mike"}
3: {lastName: "Johnson"}
4: {email: "mike.johnson@mail.com"}
5: {role: "user"}

postData的构建方式如下:


 var row = $(this).parents("tr");
                        var id = [{ id: dataTable.row(row).data().Id }];

                        divFields = row.find("div.editable").map(function () {
                            var value = this.className === "editable changed" ? this.innerText : null;
                            return {
                                [this.dataset.name]: value
                            }

                        }).get();

                        selectFields = row.find("select.editable").map(function () {
                            var value = this.className === "editable changed" ? $(this).find(":selected").text() : null;
                            return {
                                [this.dataset.name]: value
                            }

                        }).get();

                        var fields = id.concat(divFields.concat(selectFields));

                        var postData = Object.assign({}, fields);

1 个答案:

答案 0 :(得分:1)

在您的示例中,您正在构建一个fields数组,该数组代表表单值,最终看起来像这样:

[
    { id: 10 },
    { userName: "Mike99" },
    { firstName: "Mike" },
    { lastName: "Johnson" },
    { email: "mike.johnson@mail.com" },
    { role: "user" }
]

使用Object.assign({}, fields)时,最终将fields的属性复制到新对象中,但是这些属性为0 ... 5。这意味着您最终得到一个看起来像这样的对象:

{
    0: { id: 10 },
    1: { userName: "Mike99" },
    2: { firstName: "Mike" },
    3: { lastName: "Johnson" },
    4: { email: "mike.johnson@mail.com" },
    5: { role: "user" }
}

当jQuery将其序列化为application/x-www-form-urlencoded内容类型时,它最终将成为ASP.NET Core模型绑定程序无法解析的内容。您已经包含了问题中的内容,因此在此不再赘述。

一种解决方案(有多种可能),它使用...上的散布运算符(fields),如下所示:

Object.assign({}, ...fields)

这会将fields拆分为它包含的各个对象,并将它们分配给结果对象。