【问题标题】:Asp.net Core 2.0 Razor Pages Ajax PostAsp.net Core 2.0 Razor Pages Ajax Post
【发布时间】:2018-03-30 22:52:20
【问题描述】:

我正在尝试通过 jquery ajax 调用从 Razor 页面检索用户列表。

Users.cshtml.cs 页面:

public ActionResult OnPostList(string FirstName, string LastName,string IsActive)
{
        var data=(from s in _db.SecurityUser
                 where s.FirstName.Contains(FirstName) && s.LastName.Contains(LastName) && (IsActive=="" || (IsActive =="Y" && s.IsActive==true) || (IsActive == "N" && s.IsActive == false))
                 select s).OrderBy(s=>s.FirstName);
        return new JsonResult(data);
}

JS 调用:

$.ajax({
    type: "POST",
    url: "/Security/Users?handler=List",
    data: JSON.stringify({
        FirstName: $("#txtFirstName").val(),
        LastName: $("#txtLastName").val(),
        IsActive: $("#ddActive").val()
    }),
    contentType: "application/json",
    dataType: "json",
    success: function (response) {
        var d = response.d;
        var tblBody = $("#tblUsers > tbody");
        tblBody.empty();
        $.each(d, function (i, item) {
            var modifiedDate = new Date(parseInt(item.ModifiedDate.substr(6)));
            var $tr = $('<tr>').append(
                $('<td>').html("<a href='javascript:void(0)' onclick='fnDialogShow(" + item.UserID + ")'>Edit</a>"),
                $('<td>').text(item.FirstName),
                $('<td>').text(item.LastName),
                $('<td>').text(item.IsActive ? "Yes" : "No")
            ).appendTo(tblBody);

        });
    },
    failure: function (response) {
        alert(response.d);
    }

});

当它调用时,我得到一个 400 错误。试图弄清楚我做错了什么。

【问题讨论】:

  • 您正在调用操作“Users”而不是“OnPostList”。

标签: ajax razor asp.net-core-2.0


【解决方案1】:

您的 Ajax 请求 URL 格式正确。需要注意的一件事是,Razor Pages 旨在防止(CSRF/XSRF)攻击。因此,防伪令牌生成和验证自动包含在 Razor 页面中。我相信这就是这里的问题。如果您的 HTML 中有表单标签,则您的页面上可能存在防伪令牌。但是您需要在 Ajax 请求中传递相同的内容。

首先,使用@Html.AntiForgeryToken() 添加防伪令牌(如果不存在)。

然后,修改您的 Ajax 请求以在请求标头中发送相同的内容。

喜欢,

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

阅读这篇文章Handle Ajax Requests in ASP.NET Core Razor Pages,了解更多关于使用 ASP.NET Core razor 页面发出 ajax 请求的信息。

【讨论】:

【解决方案2】:

对于 .net core 2.1,此博客中的解决方案有所帮助 https://www.thereformedprogrammer.net/asp-net-core-razor-pages-how-to-implement-ajax-requests/

如果页面不包含带有post方法的表单,添加防伪令牌@Html.AntiForgeryToken()

你可以开始触发 ajax 请求,重要的部分是在这里设置 headers

$.ajax({
                type: "POST",
                url: "/Customers?handler=Delete",
                data: { id: id },
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                // AntiforgeryToken is required by RazorPages
                headers: {
                    RequestVerificationToken: $('input:hidden[name="__RequestVerificationToken"]').val()
                }
            })
            .done(function () {
                alert("success");
            })
            .fail(function () { 
                alert("error");
            });

【讨论】:

    【解决方案3】:

    默认情况下,Razor Pages 旨在保护 CSRF 攻击。

    您必须将防伪令牌正确地注入到您的 ajax 请求中。

    See the Documentation.

    在 ASP.NET Core 2.0 中看起来像这样...

    首先将此代码放在剃刀视图的顶部:

    // At the top of your page
    @inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
    @functions{
        public string GetAntiXsrfRequestToken()
        {
            return Xsrf.GetAndStoreTokens(Context).RequestToken;
        }
    }
    

    然后在您的 ajax 请求中,设置令牌标头。

    $.ajax({
        type: "post",
        headers: {
            "RequestVerificationToken": '@GetAntiXsrfRequestToken()'
        },
        url: '@Url.Action("Antiforgery", "Home")',
        success: function (result) {
            alert(result);
        },
        error: function (err, scnd) {
            alert(err.statusText);
        }
    });
    

    【讨论】:

    • Xsrf.GetAndStoreTokens(Context).RequestToken; 如果您使用的是 MVC,则可能会收到 Context,但不能使用 Razor Pages。改为Xsrf.GetAndStoreTokens(HttpContext).RequestToken;
    • 不错@AdamVincent,我肯定将 MVC 与 Razor Pages 结合使用
    【解决方案4】:

    使用 HttpPost 属性标记您的 OnPostList,并将您在 ajax 调用中的 URL 更改为 /Security/OnPostList

    【讨论】:

      【解决方案5】:

      在行动中添加[HttpPost]

        [HttpPost]
          public ActionResult OnPostList(string FirstName, string LastName,string IsActive)
          {
                  var data=(from s in _db.SecurityUser
                           where s.FirstName.Contains(FirstName) && s.LastName.Contains(LastName) && (IsActive=="" || (IsActive =="Y" && s.IsActive==true) || (IsActive == "N" && s.IsActive == false))
                           select s).OrderBy(s=>s.FirstName);
                  return new JsonResult(data);
          }
      

      Users.cshtml.cs中使用了这个Script

      <script>
        var url='@(Url.Action("OnPostList","ControllerName"))';
        var firstName= $("#txtFirstName").val();
        var lastName= $("#txtLastName").val();
        var isActive= $("#ddActive").val();
        $.post(Url,{FirstName:firstName,LastName=lastName,IsActive=isActive},function(data){
            var d = data.d;
            var tblBody = $("#tblUsers > tbody");
            tblBody.empty();
            $.each(d, function (i, item) {
               var modifiedDate = new Date(parseInt(item.ModifiedDate.substr(6)));
               var $tr = $('<tr>').append(
               $('<td>').html("<a href='javascript:void(0)' onclick='fnDialogShow(" + item.UserID + ")'>Edit</a>"),
               $('<td>').text(item.FirstName),
               $('<td>').text(item.LastName),
               $('<td>').text(item.IsActive ? "Yes" : "No")
               ).appendTo(tblBody);
             });
          });
      </script>
      

      【讨论】:

        【解决方案6】:

        我对 $.ajax 有过不好的体验,我改用了 $.post。 我使用了 validateAntiforgeryToken 但它不是必需的

            $("#emailSubmit").click(function () {
        
                $.post("/Projects/SendInvite",
                    {
                        Email: $("#email").val(),
                        Message: $("#message").val(),
                        __RequestVerificationToken: $('input[name="__RequestVerificationToken"]').val()
                    }
        
                )
                return false;
        
            });
        

        这是净核心行动:

            [HttpPost]
            [ValidateAntiForgeryToken]
            public IActionResult SendInvite(string Email, string Message)
        {
        
                //MailTest();
                var json = new List<string>
                {
                Email,
                Message
                };
                return new JsonResult(json);
           }
        

        【讨论】:

          猜你喜欢
          • 2018-10-29
          • 2014-02-26
          • 2019-10-12
          • 2018-05-09
          • 2020-11-21
          • 2022-01-23
          • 2018-10-16
          • 2019-07-25
          • 2018-06-07
          相关资源
          最近更新 更多