Я работаю над ASP.NET Zero, который построен на ASP.NET Core. Я получал неверную ошибку запроса, когда использовал элемент управления KendoUI Upload на одной из своих страниц. После долгих исследований и расследований я понял, что запрос HTTP POST Ajax не работает с ошибкой 400 неверного запроса. В моих примерах кода ниже есть некоторые строки с комментариями для других тестируемых мной сценариев. Ни одна из существующих публикаций в переполнении стека не решила мою проблему. I Ниже мой вызов ajax:
$.ajax({
url: "/test/TestCall",
type: 'Post',
/* data: JSON.stringify({ "Param1": "test" }),
dataType:"json",
processData: false, */// tell jQuery not to process the data
contentType: "application/json", // tell jQuery not to set contentType
success: function (result) {
var res = result;
},
error: function (jqXHR) {
var z = 3;
},
complete: function (jqXHR, status) {
var x = 10;
}
});
Мой код контроллера: Я также пробовал не расширять MyTestProjectControllerBase и просто использовать базовый класс Controller. Это не работает.
public class TestController : MyTestProjectControllerBase
{
public IActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult TestCall()
{
//return Content("Name is:" );
return new ContentResult() { Content = "test" };
}
}
Что мне не хватает? Я пробовал пользоваться почтальоном и вижу дополнительную информацию 'Запрос не может быть выполнен из-за неправильного синтаксиса'
не мог понять этого, потратив добрые 8 часов на эту проблему. Не уверен, связана ли проблема с ядром Asp.net или нулевым asp.net. Приветствуются любые указатели.
Обновление после проверки комментариев shyju: Файл Startup.cs содержит следующий код, который включает AntiForgeryTokenAttribute.
services.AddMvc(options =>
{
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
}).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
Обновления для вызова и просмотра ajax на основе ответа shyju:
$("#backBtn").on("click", function (e) {
var t = $("input[name='__RequestVerificationToken']").val();
$.ajax({
url: "/test/TestCall",
type: 'Post',
/* data: JSON.stringify({ "Param1": "test" }),
dataType:"json",
processData: false, */
contentType: "application/json",
headers: {
"RequestVerificationToken": t
},
success: function (result) {
var res = result;
},
error: function (jqXHR) {
var z = 3;
},
complete: function (jqXHR, status) {
var x = 10;
}
});
});
Мое мнение сейчас выглядит так: удалена остальная часть html
<div id = "container">
@Html.AntiForgeryToken()
<div class = "k-edit-field label">Vendor Name</div>
</div
Нет. В этом проекте много существующих файлов. но в созданном мной контроллере нет ничего, кроме того, что я здесь скопировал. ValidateAntiForgeryToken отсутствует в моем методе действия. Вы тестировали мой код на ядре aspnet?
привет, я только что нашел ValidateAntiForgeryToken во всем решении. В startup.cs есть следующий код services.AddMvc (options => {options.Filters.Add (new AutoValidateAntiforgeryTokenAttribute ());}). SetCompatibilityVersion (CompatibilityVersion.Version_2_1) ;
можешь добавить это к вопросу. Я опубликую решение сейчас





Похоже, у вас глобально применен фильтр AutoValidateAntiforgeryTokenAttribute. Это означает, что когда вызывается метод действия HTTP Post (нормальный или ajax), фреймворк проверяет отправленные данные запроса, и если он не находит действительный токен защиты от подделки (заголовок RequestVerificationToken), он будет считаться неправильным запросом и 400 ответ будет отправлен обратно.
Чтобы решить эту проблему, вы можете явно прочитать значение скрытого ввода __RequestVerificationToken (сгенерированное помощником тега формы) и отправить его в заголовках запроса ajax.
var t = $("input[name='__RequestVerificationToken']").val();
$.ajax({
url: "/test/TestCall",
type: 'Post',
headers:
{
"RequestVerificationToken": t
},
success: function (result) {
alert("Success");
var res = result;
},
error: function (jqXHR) {
var z = 3;
},
complete: function (jqXHR, status) {
var x = 10;
}
});
Вы можете сделать код более надежным, внедрив реализацию IAntiforgery в представление / страницу и используя метод GetAndStoreTokens.
Добавьте это к своему обзору
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
@functions{
public string GetAntiXsrfRequestToken()
{
return Xsrf.GetAndStoreTokens(Context).RequestToken;
}
}
и вызовите эту функцию GetAntiXsrfRequestToken, чтобы получить значение в вашем javascript (который находится внутри файла представления)
headers:
{
"RequestVerificationToken": '@GetAntiXsrfRequestToken()'
},
Спасибо за помощь. Это не устранило проблему. однако, если я закомментирую глобальный фильтр для тестирования, это позволит пройти почтовому запросу. Вы правильно определили проблему. но решение по какой-то причине не работает. Я вижу токен, сгенерированный и переданный в вызов ajax. обновит новый вызов ajax в вопросе
Отправляет ли он необходимое значение заголовка? Пробовал ваш код и отлично работал у меня.
Я зарегистрировался на вкладке сети в Chrome; в заголовке запроса установлен токен RequestVerificationToken. Есть ли еще что-нибудь, что мне нужно проверить?
Есть ли у вас какие-либо другие фильтры на стороне вашего сервера, которые могут возвращать ответ 400?
Точно сказать не могу. что мне искать? его исходный код asp.net zero имеет много файлов
Других фильтров в startup.cs не вижу. буду продолжать поиск
Спасибо за это объяснение @Shyju. Это помогло мне решить ту же проблему. Однако я не понимаю того факта, что мой вызов ajax работал неделями без использования каких-либо заголовков для указания токена. Внезапно сегодня я получил ошибку http 400. Это почему? Я не делал никаких изменений относительно токена ни в контроллере, ни в модели, ни в представлении.
Попробуйте указать в шапке с X-XSRF-TOKEN.
Для ABP Intercept XMLHttpRequest.
Since all libraries use JavaScript's native AJAX object, XMLHttpRequest, you can define a simple interceptor to add the token to the header:
(function (send) {
XMLHttpRequest.prototype.send = function (data) {
this.setRequestHeader(abp.security.antiForgery.tokenHeaderName, abp.security.antiForgery.getToken());
return send.call(this, data);
};
})(XMLHttpRequest.prototype.send);
Для abp.security.antiForgery.tokenHeaderName значение по умолчанию - X-XSRF-TOKEN.
В Core - убедитесь, что ваш тег <form> включает method = "post".
Этот метод требуется для вызова помощника тега формы, который автоматически добавляет в форму токен защиты от подделки. (Я случайно отказался от этого метода и не заметил, потому что публиковал его с помощью ajax.)
В Net Core RazorPages вам нужно будет передать AntiForgeryToken с помощью запроса JQuery Ajax Post. если у вас есть тег формы с Method = Post, вам не нужно беспокоиться об его отправке.
$.ajax({
type:"post",
url:"?Handler=Update",
dataType:"json",
beforeSend: function(xhr){
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name = "__RequestVerificationToken"]').val());
},
success: function(result){
// do something
}
});
Затем на вашей странице Razor
@using Microsoft.AspNetCore.Antiforgery
@inject IAntiforgery antiforgery
@{
var token = antoforgery.GetAndStoreTokens(HttpContext).RequestToken;
}
Не забудьте добавить
@Html.AntiForgeryToken()
Затем в вашем StartUp.cs внутри метода ConfigureServices добавьте
services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
С кодом, которым вы поделились, он не должен выдавать ответ 400. Я просто скопировал и вставил ваш код в локальный проект, и он мне вернул 200 OK. Похоже, вы не делитесь кодом, который вызывает ответ 400. Есть ли у вашего метода действия атрибут
ValidateAntiForgeryToken?