Почему этот базовый вызов ajax дает мне 400, а не увольняет контроллер? - PullRequest
0 голосов
/ 02 июля 2018

Это проблема только для меня в моем новейшем веб-приложении dot net core 2, оно работает в предыдущих приложениях dot net без проблем.

У меня есть пользовательский файл javascript с путями к различным серверам, на которых размещен мой сайт (в основном, dev, test, live).

Мой вызов ajax выглядит следующим образом:

var gameid = '@Html.Raw(Model.Id)';
    $.ajax({
        type: 'GET',
        url: url() + "UserGames/HasGame?id=" +gameid,
        cache: false,
        success: function (data) {
            console.log(data);
        },
        error: function (req, status, err) {
            console.log('Something went wrong', status, err);
        }
    });

URL (), о котором идет речь, просто просматривает мой локальный сервер во время тестирования (* обратите внимание, этот порт был отредактирован, это правильно):

function url() {
return "https://localhost:4432/";
}

Ошибка не срабатывает, поскольку не достигает даже используемой функции контроллера.

Я абсолютно смущен тем, почему это не работает, я мог понять, получал ли я какую-то ошибку назад, но я использовал вызовы ajax во всех своих приложениях и вообще не имел этой проблемы до использования ядра 2 .

Что-нибудь изменилось, что могло повлиять на то, как вы используете ajax-вызовы?

Метод, который пытается запустить, но я упомянул, что это не удар по контроллеру (ПРИМЕЧАНИЕ: у метода действительно есть код, он просто не поражает контроллер в первую очередь)

[HttpGet]
[ValidateAntiForgeryToken]
public async Task<IActionResult> HasGame(int id)
{
    //stuff in here
}

Ответы [ 2 ]

0 голосов
/ 03 июля 2018

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

type: 'GET',
url: '@Url.Action("HasGame", "UserGames")',
data: {id : gameid},

И контроллер в ядре 2, похоже, совсем не любит, когда вы объявляете [HttpGet], поэтому я также удалил это.

Спасибо за всю предоставленную помощь.

0 голосов
/ 02 июля 2018

Вы получаете ответ 400 (Bad Request ), потому что платформа ожидает RequestVerificationToken как часть запроса. Структура использует это для предотвращения возможных атак CSRF. Если в вашем запросе нет этой информации, платформа вернет неверный запрос 400 . Ваш текущий код не отправляет его.

Вы можете исправить это, отправив явно RequestVerificationToken

Помощник тега формы автоматически создает скрытый ввод со значением атрибута имени __RequestVerificationToken и сохраняет токен в качестве значения скрытого ввода.

var token = $("[name='__RequestVerificationToken']").val();
var gameid = '@Html.Raw(Model.Id)';
$.ajax({
    type: 'GET',
    url: url() + "UserGames/HasGame?id=" +gameid,
    headers:{ "RequestVerificationToken": token },
    success: function (data) {
        console.log(data);
    },
    error: function (req, status, err) {
        console.log('Something went wrong', status, err);
    }
});

В приведенном выше примере мы используем некоторый код jQuery для получения элемента ввода с именем __RequestVerificationToken и чтения его значения. Более надежный подход - внедрить реализацию IAntiforgery в представление и использовать метод GetAndStoreTokens.

Мы будем вводить IHttpContextAccessor в вид. Поэтому убедитесь, что он правильно подключен к DI. Добавьте эту строку в метод ConfigureServices ваших классов запуска.

services.AddTransient<IHttpContextAccessor, HttpContextAccessor>();

Теперь, по вашему мнению, вы можете ввести IHttpContextAccessor и IAntiforgery, а затем вызвать GetAndStoreTokens, чтобы получить токен. Здесь я обернул это в вспомогательную функцию.

@inject Microsoft.AspNetCore.Http.IHttpContextAccessor HttpContext
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
@functions{
    public string GetAntiXsrfRequestToken()
    {
        return Xsrf.GetAndStoreTokens(HttpContext.HttpContext).RequestToken;
    }
}

Теперь позже в моем js я могу вызывать этот метод внутри своего кода javascript вместо использования jQuery для получения входного значения.

var token = "@GetAntiXsrfRequestToken()";
var gameid = '@Html.Raw(Model.Id)';
$.ajax({
    type: 'GET',
    url: url() + "UserGames/HasGame?id=" +gameid,
    headers:{ "RequestVerificationToken": token },
    success: function (data) {
        console.log(data);
    },
    error: function (req, status, err) {
        console.log('Something went wrong', status, err);
    }
});

или Просто удалите оформление атрибута [ValidateAntiForgeryToken] из метода действия, что исключает эту проверку.

Я рекомендую вам воспользоваться методом [ValidateAntiForgeryToken]. Отправьте токен как часть вашего запроса (первый подход)

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