如何ASP.NET Core Razor中處理Ajax請求
阿新 • • 發佈:2019-01-26
在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請求了。折騰了半天總算解決了。。。。解決了之後發現自己之前鑽了牛角尖,,,其實還有更簡單的方法。。太晚了,明天測試一下,可行的話補回來。
原文地址:https://www.cnblogs.com/dazhuangtage/p/8322452.html
.NET社群新聞,深度好文,歡迎訪問公眾號文章彙總 http://www.csharpkit.com