ASPNET CORE Ajax Post导致400错误请求

时间:2019-01-07 18:43:07

标签: ajax post asp.net-core

我正在使用基于ASP.NET Core的ASP.NET Zero。 当我在其中一个页面上使用KendoUI Upload控件时,出现了严重的请求错误。经过大量研究和调查,我意识到HTTP POST Ajax请求失败,并出现400错误的请求错误。下面的代码示例在我测试的其他场景中有一些注释行。堆栈溢出中的现有帖子均未解决我的问题。我在下面是我的Ajax电话:

 $.ajax({
            url: "/test/TestCall",
            type: 'Post',
           /* data: JSON.stringify({ "Param1": "test" }),
            dataType:"json",
            processData: false,  */// tell jQuery not to process the data
            contentType: "application/json",  // tell jQuery not to set contentType
            success: function (result) {
                var res = result;
            },
            error: function (jqXHR) {
                var z = 3;
            },
            complete: function (jqXHR, status) {
                var x = 10;
            }
        });

我的Controller代码是:我也尝试不从MyTestProjectControllerBase扩展而仅使用Controller基类。它没有用。

public class TestController : MyTestProjectControllerBase
{
    public IActionResult Index()
    {
        return View();
    }

   [HttpPost]
    public ActionResult TestCall()
    {
        //return Content("Name is:" );
        return new ContentResult() { Content = "test" };
    }
}

我想念什么?我尝试使用邮递员,但看到此附加信息 “由于语法错误,无法满足请求”

在此问题上花费了8个小时后仍无法解决。不确定问题出在Asp.net核心还是asp.net零。任何指针将不胜感激。

在检查了shyju的评论后进行更新: Startup.cs文件包含以下代码,可启用AntiForgeryTokenAttribute

 services.AddMvc(options =>
        {
            options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
        }).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

根据shyju的回答更新到ajax调用和查看:

  $("#backBtn").on("click", function (e) {
        var t = $("input[name='__RequestVerificationToken']").val();
        $.ajax({
            url: "/test/TestCall",
            type: 'Post',
           /* data: JSON.stringify({ "Param1": "test" }),
            dataType:"json",
            processData: false,  */
            contentType: "application/json",  
            headers: {
                "RequestVerificationToken": t
            },
            success: function (result) {
                var res = result;
            },
            error: function (jqXHR) {
                var z = 3;
            },
            complete: function (jqXHR, status) {
                var x = 10;
            }
        });
    });

我的视图现在看起来像这样:删除了html的其余部分

<div id="container">
    @Html.AntiForgeryToken()
    <div class="k-edit-field label">Vendor Name</div>
</div

3 个答案:

答案 0 :(得分:0)

好像您已全局应用AutoValidateAntiforgeryTokenAttribute过滤器。这意味着当调用HTTP Post操作方法(普通或ajax)时,框架将检查提交的请求数据,如果找不到有效的防伪令牌(RequestVerificationToken标头),则将其视为错误的请求,然后将返回400响应。

要解决此问题,您可以显式读取__RequestVerificationToken隐藏输入的值(由表单标签助手生成)并将其发送到ajax请求标头中。

var t = $("input[name='__RequestVerificationToken']").val();

$.ajax({
    url: "/test/TestCall",
    type: 'Post',
    headers:
    {
        "RequestVerificationToken": t
    },
    success: function (result) {
        alert("Success");
        var res = result;
    },
    error: function (jqXHR) {
        var z = 3;
    },
    complete: function (jqXHR, status) {
        var x = 10;
    }
});

通过将IAntiforgery实现注入视图/页面并使用GetAndStoreTokens方法,可以使代码更健壮。

将此添加到您的视图

@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
@functions{
public string GetAntiXsrfRequestToken()
{
    return Xsrf.GetAndStoreTokens(Context).RequestToken;
}
}

并调用此GetAntiXsrfRequestToken函数以在javascript中获取值(位于视图文件中)

headers:
{
    "RequestVerificationToken": '@GetAntiXsrfRequestToken()'
},

答案 1 :(得分:0)

尝试使用X-XSRF-TOKEN指定标题。

对于ABP Intercept XMLHttpRequest

  

由于所有库都使用JavaScript的本机AJAX对象XMLHttpRequest,因此您可以定义一个简单的拦截器以将令牌添加到标头中:

(function (send) {
    XMLHttpRequest.prototype.send = function (data) {
        this.setRequestHeader(abp.security.antiForgery.tokenHeaderName, abp.security.antiForgery.getToken());
        return send.call(this, data);
    };
})(XMLHttpRequest.prototype.send);

对于abp.security.antiForgery.tokenHeaderName,其默认值为X-XSRF-TOKEN

答案 2 :(得分:0)

在Core中-确保您的<form>标签包含method="post"

该方法是调用表单标签帮助程序所必需的,该自动将防伪令牌添加到表单中。 (我不小心放弃了该方法,并且没有注意到,因为我正在将其ajax发布。)