Asp.net core mvc ajax post для контроллера с несколькими параметрами возвращает неверный запрос - PullRequest
0 голосов
/ 29 ноября 2018

У меня есть следующие методы действия контроллера:

public class UserController : BaseController<UserController>
{
    [HttpGet]
    public IActionResult Assignment(Guid id)
    {
        return View();
    }

    [HttpPost]
    public IActionResult Assignment(Guid id, [FromBody] List<UserViewModel> assignees)
    {
        return View();
    }
}

Метод ajax в Assignment.cshtml page

$("#btn-save").click(function () {
    var url = "/User/Assignment/@Model.SelectedUser.Id";
    $.ajax({
        type: "POST",
        url: url,
        contentType: "application/json",
        data: JSON.stringify({ assignees: assignmentPage.SelectedUsers })
    });
});

Таким образом, создается URL-адрес, подобный;

http://localhost:8800/User/Assignment/f474fd0c-69cf-47eb-7281-08d6536da99f

Это единственная конфигурация маршрута в моем Startup.cs.

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

Я никогда не нажимал на Назначение post action, сервер возвращает 400 , я искал и не смог найти, как мне настроить мой маршрут для такого действия?

Ответы [ 2 ]

0 голосов
/ 29 ноября 2018

Проблема в моем случае заключается в том, что я использую AutoValidateAntiforgeryTokenAttribute configuration

services.AddMvc(options =>{
    // Automatically add antiforgery token valdaiton to all post actions.
    options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
}

Таким образом, сообщение ajax не имеет никакого токена проверки запроса, отсутствие этого токен-сервера возвращает неверный запрос,

Чтобы преодолеть это, я перешел по этой ссылке , поэтому мой окончательный рабочий код:

Assignment.cshtml

@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
@functions
{
    public string GetAntiXsrfRequestToken() => Xsrf.GetAndStoreTokens(Context).RequestToken;
}
<input type="hidden" id="RequestVerificationToken" name="RequestVerificationToken" 
       value="@GetAntiXsrfRequestToken()">

<script type="text/javascript">
    $("#btn-saveinspectors").click(function () {
        var url = "/Audit/Assignment/@Model.SelectedUser.Id";
        var assignees = JSON.stringify(assignmentPage.SelectedUsers);

        $.ajax({
            type: "POST",
            url: url,
            beforeSend: function (xhr) {
                xhr.setRequestHeader("XSRF-TOKEN", $('#RequestVerificationToken').val());
            },
            contentType: "application/json",
            data: assignees,
        });
    });
</script>

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
}

Примечание: В моем случае не любая форма на моей странице, где запростокен подтверждения генерируется автоматически.Если у вас есть форма на вашей странице, где вы делаете запрос AJAX, вы можете следовать этому сообщению

0 голосов
/ 29 ноября 2018

Данные, которые вы отправляете на свой сервер, недействительны .Он ожидает массив JSON, но вы отправляете ему объект JSON с единственным свойством, которое само является массивом.Вы получаете код состояния 400 из-за того, что JSON.NET не может проанализировать объект как массив.

Для дальнейшего пояснения, это то, что вы отправляете:

{
    "assignees": [
        { ... assignee1 ... },
        { ... assignee2 ... },
        ...
    ]
}

Однако это ожидаемый массив, поэтому он должен выглядеть следующим образом:

[
    { ... assignee1 ... },
    { ... assignee2 ... },
    ...
]

Все, что вам нужно сделать, это изменить текущую строку JSON.stringify на эту:

JSON.stringify(assignmentPage.SelectedUsers)

Альтернативный вариант - создать класс модели в вашем проекте ASP.NET Core и использовать его вместо списка строк.Вот как это будет выглядеть:

public class AssignmentModel
{
    public List<UserViewModel> Assignees { get; set; }
}

Действие Assignment будет выглядеть так:

public IActionResult Assignment(Guid id, [FromBody] AssignmentModel thisNameDoesNotMatter)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...