Как привязать параметры записи к параметрам действия в контроллере? - PullRequest
1 голос
/ 15 июня 2019

Акция такая:

[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 Ответ

1 голос
/ 15 июня 2019

В вашем примере вы создаете массив 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 на отдельные содержащиеся в нем объекты и присваивает их результирующему объекту.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...