1. 程式人生 > >如何ASP.NET Core Razor中處理Ajax請求

如何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,直接上圖

640?wx_fmt=png&wxfrom=5&wx_lazy=1

功能很簡單,就是個登入。使用者點選"登入按鈕"後利用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的語法限定,不清楚的朋友可以去看下微軟的官方文件,寫的肯定比我好。。這個程式碼乍一看,思路很清晰,專案跑起來,走一波看看。

0?wx_fmt=png

是的,你沒看錯,響應碼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請求了。折騰了半天總算解決了。。。。解決了之後發現自己之前鑽了牛角尖,,,其實還有更簡單的方法。。太晚了,明天測試一下,可行的話補回來。

原文地址:https://www.cnblogs.com/dazhuangtage/p/8322452.html

.NET社群新聞,深度好文,歡迎訪問公眾號文章彙總 http://www.csharpkit.com

640?wx_fmt=jpeg