【问题标题】:Ajax call to controller results in 400 error对控制器的 Ajax 调用导致 400 错误
【发布时间】:2019-06-19 18:28:21
【问题描述】:

我有以下指向控制器函数的 Ajax 调用:

<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>

当我单击AddNote 按钮时,我看到“正在添加注释...”消息显示,然后没有其他反应。当我在 chrome 中检查控制台时,它显示:

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

所以我知道 400 意味着错误的请求,但我不确定为什么会这样。我试过了:

  • 在数据中的“leadId”和“note”字段中添加了引号 - 没有区别。
  • 添加了警告框以在 AJAX 调用之前显示 @Model.Id 和 txtNote.value 的值,以验证它们是否正确 - 它们是正确的。
  • 在我的控制器的 AddNoteAsync 函数中放置一个断点 - 它永远不会命中
  • 将 url 字段硬编码为 /Leads/AddNoteAsync - 没有区别

由于控制器功能从未被击中,我假设 &amp;.ajax 部分有问题,但我不知道是什么。

编辑:控制器方法:

[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");
}

【问题讨论】:

  • 你的控制器外观方法是什么样的。
  • 已添加。我开始怀疑它现在是否是ValidateAntiForgeryToken 问题...
  • 您解决了这个问题吗?
  • @Alexander 确实做到了。我在这里发布了答案:stackoverflow.com/a/55578822/343311

标签: c# jquery asp.net-web-api


【解决方案1】:

您应该在发出 POST 请求时接受参数作为模型(推荐)。提议的模型将是 -

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

而Action可以是-

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

Jquery 也可以 -

<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
                },
            });
        });
    });

【讨论】:

    【解决方案2】:

    解决了这个问题。我的 AJAX 请求中缺少此内容:

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

    这来自我的 Startup.cs:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-22
      • 1970-01-01
      • 1970-01-01
      • 2013-07-09
      • 1970-01-01
      相关资源
      最近更新 更多