Home > Mobile >  ajax post to MVC controller failed with 400 Bad Request
ajax post to MVC controller failed with 400 Bad Request

Time:09-30

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?

enter image description here

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() },
  • Related