简体   繁体   中英

Ajax call to controller results in 400 error

I have the follow Ajax call that points to a controller function:

<script type="text/javascript">
    $(document).ready(function () {
        $('#AddNote').click(function () {
            $('#AddNote').addClass("disabled");

                var txtNote = document.getElementById('note');
                var result = document.getElementById('result');

                result.innerText = "Adding note...";

                $.ajax({
                    url: "@Url.Action("AddNoteAsync", "Leads")",
                    type: "POST",
                    data: { leadId: @Model.Id, note: txtNote.value },
                    async: true,
                    success: function (data) {
                        // removed
                    },
                });
            });
        });
</script>

When I click the AddNote button I see the "Adding note..." message display and then nothing else happens. When I check the console in chrome, it reads:

:44309/Leads/AddNoteAsync:1 - Failed to load resource: the server responded with a status of 400 ()

So I know 400 means bad request but I'm not sure why it's happening. I've tried:

  • Added quotes to the "leadId" and "note" field in data - made no difference.
  • Added alert boxes to show the value of @Model.Id and txtNote.value before the AJAX call to verify they are correct - they are.
  • Put a breakpoint in the AddNoteAsync function in my controller - it's never hit
  • Hard coded the url field to /Leads/AddNoteAsync - made no difference

Since the controller function is never being hit I'm assuming something is wrong with the &.ajax part but I cannot figure out what.

Edit: The controller method:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> AddNoteAsync(int? leadId, string note)
{
    ViewData["AddedNote"] = false;

    if (leadId == null)
    {
        return RedirectToAction("Index", new { initials = User.Identity.Name });
    }

    var lead = await _context.Leads.FirstOrDefaultAsync(m => m.Id == leadId);
    if (lead == null)
    {
        return RedirectToAction("Index", new { initials = User.Identity.Name });
    }

    var ownsLead = await LeadBelongsToCurrentUser(leadId.Value, User.Identity.Name);
    if (!ownsLead)
    {
        return RedirectToAction("Index", new { initials = User.Identity.Name });
    }

    _context.LeadNotes.Add(new LeadNoteModel()
    {
        LeadId = leadId.Value,
        Note = note,
        NoteDate = DateTime.Now
    });

    await _context.SaveChangesAsync();

    ViewData["AddedNote"] = true;

    return Content("Success");
}

You should accept parameters as Model while making POST request(Recommended). Proposed Model will be -

public class NoteModel
{
    public int? leadId { get; set; }
    public string note { get; set; }
}

and Action can be -

public async Task<IActionResult> AddNoteAsync(NoteModel model)
{
}

Also Jquery can be -

<script type="text/javascript">
$(document).ready(function () {
    $('#AddNote').click(function () {
        $('#AddNote').addClass("disabled");

            var txtNote = document.getElementById('note');
            var result = document.getElementById('result');
            var postData = { leadId: @Model.Id, note: txtNote.value };
            result.innerText = "Adding note...";

            $.ajax({
                url: "@Url.Action("AddNoteAsync", "Leads")",
                type: "POST",
                data: JSON.stringify(postData),
                async: true,
                success: function (data) {
                    // removed
                },
            });
        });
    });

Fixed this. I was missing this from my AJAX request:

beforeSend: function (xhr) {
   xhr.setRequestHeader("XSRF-TOKEN", $('input:hidden[name="f"]').val());
},

And this from my Startup.cs:

services.AddAntiforgery(options =>
{
    options.FormFieldName = "f";
    options.HeaderName = "XSRF-TOKEN";
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM