视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
如何ASP.NET Core Razor中处理Ajax请求
2020-11-27 22:35:08 责编:小采
文档


在ASP.NET Core Razor(以下简称Razor)刚出来的时候,看了一下官方的文档,一直没怎么用过。

今天闲来无事,准备用Rozor做个项目熟练下,结果写第一个页面就卡住了。折腾半天才搞好,下面给大家分享下解决方案。先来给大家简单介绍下Razor Razor Pages是ASP.NET Core的一项新功能,可以使编页面的编程方案更简单,更高效。Razor页面使用处理程序方法来处理传入的HTTP请求(GET / POST / PUT / Delete)。这些类似于ASP.NET MVC或WEB API的Action方法。Razor Pages遵循特定的命名约定,Handler方法也是如此。他们也遵循特定的命名约定,并与“On”前缀:和HTTP动词一样OnGet(),OnPost()等处理方法也有异步版本:OnGetAsync(),OnPostAsync()等。介绍完Razor,直接上图

功能很简单,就是个登录。用户点击"登录按钮"后利用Jquery获取文本框的值,异步提交到服务器。很简单的功能,相信大家都写过很多次了。啪啪啪几下代码就撸出来了。

##前台代码
<form method="post">
 <div class="login-ic">
 <i></i>
 <input asp-for="Login.UserName" />
 <div class="clear"> </div>
 </div>
 <div class="login-ic">
 <i class="icon"></i>
 <input asp-for="Login.PassWord" />
 <div class="clear"> </div>
 </div>
 <div>
 <ul>
 <li>
 <input type="checkbox" value="">
 <label for="brand1">记得我</label>
 </li>
 </ul>
 <a href="#" rel="external nofollow" >
 忘记密码?
 </a>
 </div>
 <div class="log-bwn">
 <input type="button" value="登录">
 </div>
 <div class="log-bwn">
 <input type="button" value="注册">
 </div>
</form>
##Script代码
$("#btnLogin").click(function () {
 $.post('/user/Login?hanler=LoginIn', { UserName:$("#UserName").val(), PassWord:$("#PassWord").val() }, function (data) {
 console.log(data);
 });
 });
##后台代码
public class LoginModel : PageModel
{

 private UserServiciCasee _userService;

 public LoginModel(UserServiciCasee userService)
 {
 _userService = userService;
 }

 public void OnGet()
 {
 }
 [BindProperty]
 public UserLoginDto Login { get; set; }
 public async Task<ActionResult> OnPostLoginInAsync()
 {
 //if (ModelState.IsValid)
 //{
 // var user = await _userService.LoginAsync(Login);
 // if (user != null)
 // {
 // return new JsonResult(ApiResult.ToSucess("登录成功!"));
 // }
 // return new JsonResult(ApiResult.ToFail("帐号密码错误!"));
 //}
 return new JsonResult(ApiResult.ToFail("参数填写错误,请检查!"));
 }
}

首先解释下/user/Login?hanler=LoginIn这个Url是什么意思,user是我Page下的一个目录,Login是一个页面,LoginIn是页面里面对应的一个方法。这个url的就是把这个请求交给OnPostLoginInAsync()方法处理。至于为什么是LoginIn而不是OnPostLoginInAsync,在文章开头也提到过,这是Rozar的语法限定,不清楚的朋友可以去看下微软的官方文档,写的肯定比我好。这个代码乍一看,思路很清晰,项目跑起来,走一波看看。

 

是的,你没看错,响应码400。各种姿势试了半天,就是400,你现在一定想知道,上面的代码有什么问题。那么,上面的代码没有错。原因是,Razor被设计为可以自动防止跨站请求伪造(CSRF / XSRF)攻击。你不必编写任何其他代码。Razor页面中自动包含防伪令牌生成和验证。这里请求失败,是因为POST没有提交AntiForgeryToken。有两种方法可以添加AntiForgeryToken。

在ASP.NET Core MVC 2.0中,FormTagHelper为HTML表单元素注入反伪造令牌。例如,Razor文件中的以下标记将自动生成防伪标记:

<form method="post">
<!-- form markup -->
</form>

明确添加使用 @Html.AntiForgeryToken()

要添加AntiForgeryToken,我们可以使用任何方法。这两种方法都添加了一个隐藏名称的输入类型__RequestVerificationToken。Ajax请求应将请求头中的防伪标记发送到服务器。所以,修改后的Ajax请求看起来像这个样子:

$("#btnLogin").click(function () {
 $.ajax({
 type: "POST",
 url: "/user/Login?handler=LoginIn",
 beforeSend: function (xhr) {
 xhr.setRequestHeader("XSRF-TOKEN",
 $('input:hidden[name="__RequestVerificationToken"]').val());
 },
 data: { UserName: $("#UserName").val(), PassWord: $("#PassWord").val() },
 success: function (response) {
 console.log(response);
 },
 failure: function (response) {
 alert(response);
 }
 });
 });

改良后的代码在发送请求前在请求头中增加了"XSRF-TOKEN"标识,值为表单自动生成的防伪标记。由于“XSRF-TOKEN”是我们自己加的,框架本身不会识别,所以我们需要把这个标记添加到框架:

public void ConfigureServices(IServiceCollection services)
{
 services.AddMvc();
 services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
}

现在服务端就可以正常收到Post请求了。折腾了半天总算解决了。。解决了之后发现自己之前钻了牛角尖,,,其实还有更简单的方法。太晚了,明天测试一下,可行的话补回来。

下载本文
显示全文
专题