1. 程式人生 > >【ASP.NET Core】解決“The required antiforgery cookie "xxx" is not present”的錯誤

【ASP.NET Core】解決“The required antiforgery cookie "xxx" is not present”的錯誤

view 請求 cep lec hidden 擴展方法 url builder 驗證

當你在頁面上用 form post 內容時,可能會遇到以下異常:

The required antiforgery cookie "????????" is not present.

咱們來重現一下錯誤。新建一個 ASP.NET Core 項目,模板選【空】就行了,這是老周最喜歡的項目模板,空 == 自由。

在項目下建一個目錄,叫 Pages,用來放 Razor 頁面;然後建一個 Index.cshtml 頁。

技術分享圖片

之所以叫 Index.cshtml,是因為 Index 是默認頁的名字,這樣輸入根 URL 就能訪問。如果不叫 Index 呢,比如這樣。

技術分享圖片

此時你可以在根 URL 後面加上 demo 來訪問,如果想在根目錄下訪問,也可以在 Startup.ConfigureServices 方法中配置頁面路由。

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().AddRazorPagesOptions(o =>
            {
                o.Conventions.AddPageRoute("/Demo", "");
            });
        }

寫路徑時一定要註意大小寫,在瀏覽器中輸入時不需要註意,但在編程時要註意。AddPageRoute 方法是個擴展方法,pagename 參數表明你要的目標頁面,比如我要到達 /Demo 頁,route 參數設置路由,空字符串表示根路徑。即我在瀏覽器中輸入 http://somehost/,就能定位到 http://somehost/Demo 頁。

如果 pagename 為 /users/newone,route 參數為 new,那麽,你訪問 http://somehost/new 就會指向 http://somehost/users/newone。

你得註意的是,這個 razor page 的路由規則只用於 Web Pages,不是 MVC 的路由規則,這個設置對 MVC 是不起作用的,MVC 可以用類似 {controller]/{action}/{id} 的路由,這個相信你很熟練了(當然,前提是你寫過 MVC 應用)。

順便在 Configure 方法中加上 use 代碼,不管是 Web Pages 還是 MVC 都要加上。

        public
void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseMvc(); }

現在可以弄一下頁面了。打開頁面,你發現找不到對應的 PageModel 類,這裏老周推薦用 _ViewImports 文件來處理。

在 Pages 目錄下添加一個視圖導入文件。

技術分享圖片

然後,引入要用的命名空間。

@using WebSample09
@using WebSample09.Pages

但是這不夠完善,還要加一行。

@namespace WebSample09.Pages

@namespace 指令用來設定 Razor 頁所生成代碼的命名空間,這樣就可以確保頁面與 PageModel 類型處於同一個命名空間,可以避免將來發生各種錯誤。

保存並關閉導入頁,回到剛剛添加的頁面。

@page
@model DemoModel

<!doctype html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
    <title>示例</title>
</head>
<body>
    <form method="post">
        <label for="parm">請隨便輸入:</label>
        <input type="text" name="parm" />
        <button type="submit">提交</button>
    </form>
</body>
</html>

打開對應的 PageModel 類代碼,寫一個 OnPost 方法。

public void OnPost(string parm)
        {
            ViewData["data"] = $"你輸入的的值是:{parm}";
        }

在 POST 之後,通過 parm 參數(與頁面 form 元素中字段命名相同,會自動賦值)獲取輸入的內容,存到 ViewData 中,為了在頁面上顯示,我們回到剛才的頁面,加一個 p 元素,用來顯示輸入內容。

  <p>@ViewData["data"]?.ToString()</p>

好,現在可以測試了。

運行,進入頁面。

技術分享圖片

輸入內容,點按鈕提交,會收到 400 錯誤。

技術分享圖片

此時 Console Log 記錄下一個異常。

技術分享圖片

即我們開頭所說的那個錯誤,這個驗證主要為了安全考慮,防止別人盜了你的數據然後跨域欺騙服務器。

那麽,咋解決呢?說出來你可能不信,很簡單。

打開剛剛咱們加到項目中的那個視圖導入頁,然後添加一個 form 元素的 Tag Helper 就行了。

@addTagHelper  Microsoft.AspNetCore.Mvc.TagHelpers.FormTagHelper, Microsoft.AspNetCore.Mvc.TagHelpers

格式是這樣的,很常規,就是 .net 類型的表示方法,用英文的逗號隔開,前面是類型(包括命名空間),後面是程序集名稱。

添加標記幫助器前,代碼編輯器中是顯示為這種顏色的。

技術分享圖片

添加標記幫助器後,顯示為這種顏色。

技術分享圖片

這時候就可以了。

技術分享圖片

咱們不妨對比一下,看看應用標記 Helper 前後輸出到客戶端的 HTML 有啥不同。

在未使用標記幫助器前,提交時會出現 400 錯誤,生成的 HTML 如下:

<form method="post">
        <label for="parm">請隨便輸入:</label>
        <input name="parm" type="text">
        <button type="submit">提交</button>
</form>

基本是原文輸出。

應用 form 元素幫助器後,生成的 HTML 如下:

<form method="post">
        <label for="parm">請隨便輸入:</label>
        <input name="parm" type="text">
        <button type="submit">提交</button>
    <input name="__RequestVerificationToken" type="hidden" value="CfDJ8DEAGDEorWJFuzYOfcGEJpSWrKHd5Qrw4jdARVRF3SwAS-TChnUQHEsFWxtXTk7IDCmpRAB241ucR6kdZA-sRBHnsyOe01ymGLs-DONlZYmB-MzvmXgJmKcn2ZrYMN-Br8fj25nX_zvuwzhyNQ42Das" />
</
form>

多了一個名為 __RequestVerificationToken 的隱藏元素,標識當前請求會話,防止被人冒用。

順便補充一下,如果你想導入各種 Tag Helper ,可以把類型名改為 * (星號,通配符)。

@addTagHelper  *, Microsoft.AspNetCore.Mvc.TagHelpers

好了,今天的內容扯到這兒了,88。

【ASP.NET Core】解決“The required antiforgery cookie "xxx" is not present”的錯誤