當你在頁面上用 form post 內容時,可能會遇到以下異常: The required antiforgery cookie "????????" is not present. 咱們來重現一下錯誤。新建一個 ASP.NET Core 項目,模板選【空】就行了,這是老周最喜歡的項目模板,空 == ...
當你在頁面上用 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。