Not for the first time, I'm seeing that my Razor Pages seem to be handling GET/POST actions strangely when posting with ajax.
The latest example looks like this:
@inject IAntiforgery antiForgery
@{
ViewData["Title"] = "Disclaimers";
Layout = "~/Pages/Shared/_Blade.cshtml";
var token = antiForgery.GetAndStoreTokens(HttpContext).RequestToken;
}
$(".save-button").on("click", function(e) {
e.preventDefault;
const body = document.querySelector(".editor").innerText;
let disclaimer = {
clientid: parseInt($("#Disclaimer_Client_Id").val()),
description: $("#Disclaimer_Description").val(),
type: $("#Disclaimer_Type").val(),
markup: body
};
$.ajax({
method: "GET",
url: "./Create?handler=Create",
headers: {
"RequestValidationToken": "@token"
},
data: disclaimer,
dataType: "application/json",
success: function (data) {
console.log(data);
},
error: function (data) {
console.log(data);
}
});
});
I've done it this way because I'm using quilljs
which employs a div for it's rich text editor. I can't use asp-for
bindings on the div to bind it to the model.
public async Task<IActionResult> OnGetCreate(CreateDisclaimerViewmodel model)
{
var disclaimer = new Disclaimer
{
Created = DateTime.Now,
CreatedBy = User.Identity.Name,
Description = model.Description,
Markup = model.Markup,
Type = model.Type
};
if (model.ClientId > 0)
{
disclaimer.Client = await context.Clients.FindAsync(model.ClientId);
}
context.Disclaimers.Add(disclaimer);
await context.SaveChangesAsync();
return Redirect("/Disclaimers/Index");
}
With the code set up as using a GET method, it all works, but in this case, it should clearly be a POST.
Change it to a POST however and an empty response is returned with HTTP 400...
$(".save-button").on("click", function(e) {
e.preventDefault;
const body = document.querySelector(".editor").innerText;
let disclaimer = {
clientid: parseInt($("#Disclaimer_Client_Id").val()),
description: $("#Disclaimer_Description").val(),
type: $("#Disclaimer_Type").val(),
markup: body
};
$.ajax({
// Only the method changes here, everything else is above.
method: "POST",
url: "./Create?handler=Create",
headers: {
"RequestValidationToken": "@token"
},
data: disclaimer,
dataType: "application/json",
success: function (data) {
console.log(data);
},
error: function (data) {
console.log(data);
}
});
});
And the page model:
// Only the method changes (OnGetCreate becomes OnPostCreate).
public async Task<IActionResult> OnPostCreate(CreateDisclaimerViewmodel model)
{
var disclaimer = new Disclaimer
{
Created = DateTime.Now,
CreatedBy = User.Identity.Name,
Description = model.Description,
Markup = model.Markup,
Type = model.Type
};
if (model.ClientId > 0)
{
disclaimer.Client = await context.Clients.FindAsync(model.ClientId);
}
context.Disclaimers.Add(disclaimer);
await context.SaveChangesAsync();
return Redirect("/Disclaimers/Index");
}
This clearly should be a POST request but it simply won't work when using POST.
So what am I missing or misunderstanding? And since the solution can't be to use GET, what's the solution?