$.ajax 调用 Asp.Net Core Razor Page 后台代码

目录
参考资料:

GET 请求

Razor Page 后台代码:
/Pages/Books/Index.cshtml.cs

        public async Task<ActionResult> OnGetBookListAsync()
        {
            var bookDtos = await _bookAppService.GetListAsync(new PagedAndSortedResultRequestDto() { });
            return new JsonResult(bookDtos);
        }

js调用
/Pages/Books/Index.js

$.ajax({
        type: 'GET',
        url: "?handler=BookList",
    })

url的规则是:?handler= 加上 OnGetBookListAsync 中的BookList
即:后台方法:OnGetXyzAsync(), 则 url:?handler=Xyz

POST请求

发起post请求时,Asp.Net Core 为了防止 XSSh和 CSRF引发的网站安全问题, js 直接访问后台代码是会报错的

Razor Pages 由防伪造验证保护,FormTagHelper 将防伪造令牌注入 HTML 窗体元素,防止跨站点请求伪造 (XSRF/CSRF)。
XSS:跨站脚本(Cross-site scripting,通常简称为XSS)是一种网站应用程序的安全漏洞攻击,是代码注入的一种。它允许恶意用户将代码注入到网页上,其他用户在观看网页时就会受到影响。这类攻击通常包含了HTML以及用户端脚本语言。
CSRF:跨站请求伪造(英语:Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF, 是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。
由于以上的问题,直接ajax post请求会出错

首先,在Startup.csConfigureServices()方法中,添加:

services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");

然后在/Pages/Books/Index.cshtml中添加

@Html.AntiForgeryToken()

/Pages/Books/Index.cshtml中定义POST 方法

        public async Task<ActionResult> OnPostDeleteBookAsync(string id)
        {
            await _bookAppService.DeleteAsync(new Guid(id));
            return NoContent();
        }

最后js调用:

      let params = {
          "id": data.record.id
      };

      $.ajax({
          type: 'POST',
          //contentType: 'application/json',
          headers: {
              "XSRF-TOKEN": $('input:hidden[name="__RequestVerificationToken"]').val()
          },
          url: `?handler=DeleteBook`,
          data: params
      }).then(function () {

      })

注意:

  • url的规则是:?handler= 加上 OnPostDeleteBookAsync 中的BookList
    即:后台方法:OnPostXyzAsync(), 则 url:?handler=Xyz

  • 解决Asp.Net Core 为了防止 XSSh和 CSRF引发的网站安全问题, js 直接问后台代码是会报错的问题:

          headers: {
              "XSRF-TOKEN": $('input:hidden[name="__RequestVerificationToken"]').val()
          },
  • 不能是 contentType: 'application/json', 而是取默认值: contentType: 'application/x-www-form-urlencoded'

  • Asp.net Core框架能自动类型转换
    后台方法:

public async Task<ActionResult> OnPostDeleteBookAsync(string id) {....}

id 的类型也可以是Guid

public async Task<ActionResult> OnPostDeleteBookAsync(Guid id)

,前端js传id时值为string,Asp.net Core框架能自动转化为Guid类型

POST对象参数

有时,POST请求参数是一个对象,

Razor Page 后台代码:
/Pages/Books/Index.cshtml.cs

        public async Task<ActionResult> OnPostDeleteBookAsync(DeleteBookViewModel vm)
        {
            //await _bookAppService.DeleteAsync(new Guid(id));
            await _bookAppService.DeleteAsync(vm.id);
            return NoContent();
        }

        public class DeleteBookViewModel
        {
            public Guid id { get; set; }
            public string msg { get; set; }
        }

js调用
/Pages/Books/Index.js

      let params = {
          "id": data.record.id,
          "msg": "just for testing!"
      };

      $.ajax({
          type: 'POST',
          //contentType: 'application/json',
          contentType: 'application/x-www-form-urlencoded',
          headers: {
              "XSRF-TOKEN": $('input:hidden[name="__RequestVerificationToken"]').val()
          },
          url: `?handler=DeleteBook`,
          data: params
      }).then(function () {

      })

注意:
不能是 contentType: 'application/json', 而是取默认值: contentType: 'application/x-www-form-urlencoded'

如果 contentType: 'application/json',即
js调用
/Pages/Books/Index.js

            let params = {
                "id": data.record.id,
                "msg": "just for testing!"
            };

            $.ajax({
                type: 'POST',
                contentType: 'application/json',
                //contentType: 'application/x-www-form-urlencoded',
                headers: {
                    "XSRF-TOKEN": $('input:hidden[name="__RequestVerificationToken"]').val()
                },
                url: `?handler=DeleteBook`,
                data: JSON.stringify(params)
            }).then(function () {
                abp.notify.info(l('SuccessfullyDeleted'));
                dataTable.ajax.reload();
            })

其中,使用 contentType: 'application/json', data参数就得使用JSON.stringify(params)将参数序列化

Razor Page 后台代码,得使用 [FromBody] 修饰参数
/Pages/Books/Index.cshtml.cs

        public async Task<ActionResult> OnPostDeleteBookAsync([FromBody]DeleteBookViewModel vm)
        {
            await _bookAppService.DeleteAsync(vm.id);
            return NoContent();
        }

        public class DeleteBookViewModel
        {
            public Guid id { get; set; }
            public string msg { get; set; }
        }

对象参数的写法是:[FromBody]DeleteBookViewModel vm

上一篇:最新2021年.NET5从0基础到精通视频教程


下一篇:CodeGo.net>如何在ASP.Net MVC中使布尔HTML5属性“有条件”?