I ajax post a complex object to a .Net 5.0 controller (not a WebAPI controller). The declaration of the MVC controller and TypeScript are as below. The [HttpPost] Edit action is invoked if I post with <input type='submit' value='Save' />. However, the controller's action is not invoked at all if I post through jQuery .ajax(). The browser console says "POST https://localhost:44381/Question/Edit 400 (Bad Request)". I read many code samples and nothing indicates anything wrong with the code. Does anyone know why?
namespace theProject.Controllers {
public class BaseController: Controller {
protected BaseController(IConfiguration configuration, ILogger logger) {
.......(elided
for brevity)
}
}
}
namespace theProject.Controllers {
//ToDo: [Authorize]
public class QuestionController: BaseController {
public QuestionController(IConfiguration configuration, ILogger < QuestionController > logger): base(configuration, logger) {}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([FromBody] PostbackModel model) {
if (ModelState.IsValid) {
List < UserAnswer > newAnswers = model.NewAnswers;
List < UserAnswer > oldAnswers = model.OldAnswers;
List < UserAnswer > updatedAnswers = model.UpdatedAnswers;
UserAnswer thisAnswer = new();
if (newAnswers != null)
thisAnswer = newAnswers.Find(x => x.StageName != string.Empty);
else if (oldAnswers != null)
thisAnswer = oldAnswers.Find(x => x.StageName != string.Empty);
else if (updatedAnswers != null)
thisAnswer = updatedAnswers.Find(x => x.StageName != string.Empty);
//ToDo: call webapi Question controller to persist the data to database
return RedirectToAction(nameof(Edit), new {
stage = thisAnswer.StageName, personName = thisAnswer.personName, custID = thisAnswer.custID.ToString(), redirectFrom = "Edit"
});
} else {
return RedirectToAction("Index", "Home");
}
}
let postBackModel: AjaxPostbackModel = < AjaxPostbackModel > {};
postBackModel.NewAnswers = newAnswers
postBackModel.OldAnswers = oldAnswers;
postBackModel.UpdatedAnswers = updatedAnswers;
let thisUrl: string = $('form').prop('action');
$.ajax({
type: "POST",
url: thisUrl,
data: JSON.stringify(postBackModel),
contentType: 'application/json; charset=utf-8',
}).done(function(result) {
$('.spinnerContainer').hide();
console.log('postback result', result.message);
console.log('inserted entities', result.insetedEntities);
dialogOptions.title = 'Success';
$('#dialog')
.text('Data is saved. ' result.message)
.dialog(dialogOptions);
}).fail(function(error) {
console.log('postback error', error);
$('.spinnerContainer').hide();
dialogOptions.title = error.statusText;
dialogOptions.classes = {
'ui-dialog': 'my-dialog',
'ui-dialog-titlebar': 'my-dialog-header'
}
$('#dialog')
.text('Data is not saved')
.dialog(dialogOptions)
});
CodePudding user response:
Since you use [ValidateAntiForgeryToken]
in action,you need to add the following code to your ajax to add antoforgery token to header.
headers: { "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val() },