Using asp.net core 3.1 and I'm trying to make a Post method call using ajax when dropdown is changed, the id value from the selected dropdown will be stored in a session, but upon changing the dropdown I encounter 400
Pages/Index.cshtml.cs
[Authorize]
[AuthorizeForScopes(ScopeKeySection = "DownstreamApi:Scopes")]
public class IndexModel : PageModel
{
public void OnGet()
{
return _studentService.GetStudents();
}
public void OnPostUpdateStudent(string id)
{
HttpContext.Session.SetString("SelectedStudent", id);
}
}
Pages/Shared/_Layout.cshtml
@{
var studentList = HttpContextAccessor.HttpContext.Session.GetObject<List<SelectListItem>>("StudentList");
}
<select onchange="UpdateAll(this)" asp-items="studentList" >
<option value="all">All Students</option>
</select>
site.js
function updateAll(element){
updateStudent(element.value);
}
function updateStudent(id) {
if (id != null && id != '') {
$.ajax({
type: "POST",
url: "/Index?Handler=UpdateStudent",
data: { id: id },
success: function (result) {
},
failure: function (response) {
console.log(response);
}
});
}
}
Response:
Request URL: https://localhost:44383/Index?Handler=UpdateStudent
Request Method: POST
Status Code: 400
Remote Address: 127.0.0.1:44383
Referrer Policy: strict-origin-when-cross-origin
date: Mon, 10 Oct 2022 08:11:42 GMT
server: Microsoft-IIS/10.0
x-powered-by: ASP.NET
:authority: localhost:44383
:method: POST
:path: /Index?Handler=UpdateStudent
:scheme: https
accept: */*
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.9
content-length: 0
CodePudding user response:
- In cshtml, add
@Html.AntiForgeryToken()
2.The Ajax request should send the anti-forgery token in request header to the server. So, the modified Ajax request looks like:
function updateStudent(id) {
if (id != null && id != '') {
$.ajax({
type: "POST",
url: "/Index?Handler=UpdateStudent",
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
data: { id: id },
success: function (result) {
},
failure: function (response) {
console.log(response);
}
});
}
}
3.In startup, since the script sends the token in a header called X-CSRF-TOKEN, configure the antiforgery service to look for the X-CSRF-TOKEN header:
services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
result:
CodePudding user response:
The simplest solution (in my opinion) is to add a form element for the dropdown, which will automatically generate the anti forgery token as a hidden field (so long as the method
is set to post
):
@{
var studentList = HttpContextAccessor.HttpContext.Session.GetObject<List<SelectListItem>>("StudentList");
}
<form method="post">
<select onchange="UpdateAll(this)" asp-items="studentList" >
<option value="all">All Students</option>
</select>
</form>
Then serialise the form in the AJAX call:
function updateAll(element){
updateStudent(element);
}
function updateStudent(element) {
if (element.value != null && element.value != '') {
$.ajax({
type: "POST",
url: "/Index?Handler=UpdateStudent",
data: $(element).closest('form').serialize(),
success: function (result) {
},
failure: function (response) {
console.log(response);
}
});
}
}