Hello Joseph Kashishian ,
If you want a simpler approach that relies more on ASP.NET Core's built-in antiforgery handling, you can skip the custom middleware entirely.
The key difference: Instead of manually creating and managing the XSRF-TOKEN cookie, just use @Html.AntiForgeryToken() and send the hidden field value directly in your AJAX headers.
Razor Page (.cshtml):
@page
@model YourNamespace.Pages.AjaxPostModel
@{
ViewData["Title"] = "AjaxPost";
}
<h1>AjaxPost</h1>
<hr />
<!-- Hidden form just to generate the token -->
<form method="post">
<input type="text" id="name" placeholder="Enter name" />
<br />
<input type="text" id="datetime" placeholder="Enter datetime" />
<br />
</form>
<input type="button" id="ajaxPost" value="POST" />
<div id="result"></div>
@section Scripts {
<script>
document.getElementById("ajaxPost").addEventListener('click', async () => {
// Read the token from the hidden field
const token = document.querySelector('input[name="__RequestVerificationToken"]').value;
const result = document.getElementById("result");
const response = await fetch("/ajaxpost", {
method: "POST",
headers: {
'Content-Type': 'application/json',
'RequestVerificationToken': token,
'X-Requested-With': 'XMLHttpRequest'
},
body: JSON.stringify({
name: document.getElementById("name").value,
datetime: document.getElementById("datetime").value
})
});
if (response.ok) {
const data = await response.text();
result.innerText = data;
} else {
result.innerText = `Error: ${response.status}`;
}
});
</script>
}
PageModel (.cshtml.cs):
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace YourNamespace.Pages
{
public class AjaxPostModel : PageModel
{
public void OnGet()
{
}
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult OnPost([FromBody] PersonModel model)
{
if (Request.Headers["X-Requested-With"] == "XMLHttpRequest")
{
return Content($"Name: {model.Name}, DateTime: {model.DateTime}");
}
return BadRequest();
}
}
public class PersonModel
{
public string Name { get; set; }
public string DateTime { get; set; }
}
}
Program.cs:
builder.Services.AddAntiforgery(options =>
{
options.HeaderName = "RequestVerificationToken";
});
The main benefits of this approach:
- No custom middleware needed, ASP.NET Core handles the antiforgery cookie automatically when you use the form tag
- Fewer moving parts means less chance for errors
- The token validation happens the same way, just simpler setup
Both approaches work fine, this is just less code to maintain if you don't need the extra flexibility.
Hope this helps!