如何ASP.NET Core Razor中处理Ajax请求

在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"  id="UserName" />
                <div class="clear"> </div>
            </div>
            <div class="login-ic">
                <i class="icon"></i>
                <input  id="PassWord" asp-for="Login.PassWord" />
                <div class="clear"> </div>
            </div>
            <div style="margin-top:-0.5em;">
                <ul>
                    <li>
                        <input type="checkbox" id="brand1" value="">
                        <label for="brand1">记得我</label>
                    </li>
                </ul>
                <a href="#">
                    忘记密码?
                </a>
            </div>
            <div class="log-bwn" style="margin-top:4em;">
                <input type="button" value="登录" id="btnLogin">
            </div>
            <div class="log-bwn" style="margin-top:1em;">
                <input type="button" value="注册" onclick="location.href='/user/register'">
            </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请求了。折腾了半天总算解决了。。。。解决了之后发现自己之前钻了牛角尖,,,其实还有更简单的方法。。太晚了,明天测试一下,可行的话补回来。

ASP.NET Core Razor中处理Ajax请求的更多相关文章

  1. 如何ASP.NET Core Razor中处理Ajax请求[转载]

    在ASP.NET Core Razor(以下简称Razor)刚出来的时候,看了一下官方的文档,一直没怎么用过. 今天闲来无事,准备用Rozor做个项目熟练下,结果写第一个页面就卡住了..折腾半天才搞好 ...

  2. ASP.NET Core Web APi获取原始请求内容

    前言 我们讲过ASP.NET Core Web APi路由绑定,本节我们来讲讲如何获取客户端请求过来的内容. ASP.NET Core Web APi捕获Request.Body内容 [HttpPos ...

  3. C# -- HttpWebRequest 和 HttpWebResponse 的使用 C#编写扫雷游戏 使用IIS调试ASP.NET网站程序 WCF入门教程 ASP.Net Core开发(踩坑)指南 ASP.Net Core Razor+AdminLTE 小试牛刀 webservice创建、部署和调用 .net接收post请求并把数据转为字典格式

    C# -- HttpWebRequest 和 HttpWebResponse 的使用 C# -- HttpWebRequest 和 HttpWebResponse 的使用 结合使用HttpWebReq ...

  4. ASP.NET CORE RAZOR :将文件上传至 ASP.NET Core 中的 Razor 页面

    本部分演示使用 Razor 页面上传文件. 本教程中的 Razor 页面 Movie 示例应用使用简单的模型绑定上传文件,非常适合上传小型文件. 有关流式传输大文件的信息,请参阅通过流式传输上传大文件 ...

  5. C#编译器优化那点事 c# 如果一个对象的值为null,那么它调用扩展方法时为甚么不报错 webAPI 控制器(Controller)太多怎么办? .NET MVC项目设置包含Areas中的页面为默认启动页 (五)Net Core使用静态文件 学习ASP.NET Core Razor 编程系列八——并发处理

    C#编译器优化那点事   使用C#编写程序,给最终用户的程序,是需要使用release配置的,而release配置和debug配置,有一个关键区别,就是release的编译器优化默认是启用的.优化代码 ...

  6. C#中的函数式编程:递归与纯函数(二) 学习ASP.NET Core Razor 编程系列四——Asp.Net Core Razor列表模板页面

    C#中的函数式编程:递归与纯函数(二)   在序言中,我们提到函数式编程的两大特征:无副作用.函数是第一公民.现在,我们先来深入第一个特征:无副作用. 无副作用是通过引用透明(Referential ...

  7. 通过重建Hosting系统理解HTTP请求在ASP.NET Core管道中的处理流程[下]:管道是如何构建起来的?

    在<中篇>中,我们对管道的构成以及它对请求的处理流程进行了详细介绍,接下来我们需要了解的是这样一个管道是如何被构建起来的.总的来说,管道由一个服务器和一个HttpApplication构成 ...

  8. 学习ASP.NET Core Razor 编程系列十二——在页面中增加校验

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  9. Asp.Net Core Razor页面中使用echarts展示图形

    Asp.Net Core Razor页面中使用echarts展示图形 要在Razor页面中使用echarts显示图形,主要问题点在于如何将数据传递给js文件. 1,下载安装echarts库文件 首先引 ...

随机推荐

  1. 【java】TreeSet、Comparable、Comparator、内部类、匿名类

    package com.tn.treeSet; public class Student { private String name; private int age; public Student( ...

  2. Swift基础学习

    Swift基础学习  http://c.biancheng.net/cpp/html/2242.html 这个网站最近看了一下,对于基本语法解释概括的相对全面,如同重新练习一遍OC似的,挺全面的,谢谢 ...

  3. Kafka详细的设计和生态系统

    欢迎大家前往云加社区,获取更多腾讯海量技术实践干货哦~ 译者:人工智能资讯小编 本译文自Jean-Paul Azar 在 https://dzone.com 发表的 Kafka Detailed De ...

  4. C#中MessageBox用法大全(附效果图)

    1.最简单的,只显示提示信息 2. 可以给消息框加上标题. 3. "确定"和"取消" 4. 给MessageBox加上一个Icon,.net提供常见的Icon共 ...

  5. C++ 头文件系列(iostream)

    1. 简介 这个头文件非常特殊,它只声明了8个常用流对象. 2. 8个对象 2.1 窄字符对象(char) extern istream cin extern ostream cout extern ...

  6. 关于git的一些理论知识

    一.什么是版本控制器 好多刚用git的coder一说起git,就随口会说出版本控制器嘛,我问那是干嘛的,大部分人就回答上传代码的.然后会用,但是有些理论你问他们他们就不知道了,比如不是代码的文件就不能 ...

  7. Mysql数据库重要知识点(知了堂学习心得)

    Mysql数据库知识点 1.管理数据库语句: 使用数据库: use test; 添加数据库: create database 数据库名; create database test; 修改数据库: al ...

  8. python:发送消息给微信企业号

    # -*- coding:utf-8 -*- import requests import json ''' 基础环境:微信企业号 version:python 2.7 ''' class Send_ ...

  9. 程序猿的日常——Java中的集合列表

    列表对于日常开发来说实在是太常见了,以至于很多开发者习惯性的用到数组,就来一个ArrayList,根本不做过多的思考.其实列表里面还是有很多玩法的,有时候玩不好,搞出来bug还得定位半天.所以这里就再 ...

  10. 一起学Linux03之Linux系统目录结构

    我们用XShell登录Linux后,如果你是用root用户登录的,那么直接使用ls命令(List files 列出文件(信息). 注: Linux命令为了方便使用,都是简写.所以,每出现一个新的命令, ...