三.頁面路由操作約定 接著上篇講asp.net core 系列 7 Razor框架路由。在上篇繼續第三節 "頁面路由操作約定" 的最後一小節 AddPageRoute 。 使用 AddPageRoute 配置路由,該路由與指定頁面關聯, 使用指定的路由生成頁面鏈接。 AddPageRoute 使用 ...
三.頁面路由操作約定
接著上篇講asp.net core 系列 7 Razor框架路由。在上篇繼續第三節 "頁面路由操作約定" 的最後一小節 AddPageRoute 。
3.3. 配置頁面路由AddPageRoute
使用 AddPageRoute 配置路由,該路由與指定頁面關聯, 使用指定的路由生成頁面鏈接。 AddPageRoute 使用 AddPageRouteModelConvention 建立路由。
示例應用為 Privacy.cshtml 創建指向 /ThePrivacyPage 的路由:
options.Conventions.AddPageRoute("/Privacy", "ThePrivacyPage/{text?}");
可以通過原有 /
Privacy預設路由訪問“Privacy”頁面。http://localhost:60397/Privacy
也可以通過上面自定義的頁面路由訪問Privacy頁面。 http://localhost:60397/ThePrivacyPage
示例應用的“Privacy”頁面自定義路由允許使用可選的 text
路由段 ({text?}
)。 該頁面還在其 @page
指令中包含此可選段,以便訪問者在 /
Privacy 路由中訪問該頁面。在呈現的頁面中,為Privacy鏈接生成的 URL 顯示了已更新的路由,如下所示:
四. 頁面模型操作約定
實現 IPageApplicationModelProvider 的預設頁面模型提供程式可調用約定,這些約定旨在為頁面模型配置提供擴展點。 在生成和修改頁面發現及處理方案時,可使用這些約定。這裡繼續使用上篇講的 AddHeaderAttribute
類(一個ResultFilterAttribute)來應用響應標頭。
4.1 文件夾應用模型約定
使用 AddFolderApplicationModelConvention 創建並添加 IPageApplicationModelConvention,後者可以為指定文件夾下的所有頁面調用 PageApplicationModel 實例上的操作。 示例演示瞭如何使用 AddFolderApplicationModelConvention
將標頭 OtherPagesHeader
添加到應用的OtherPages 文件夾內的頁面:
//文件夾應用模型約定 options.Conventions.AddFolderApplicationModelConvention("/OtherPages", model => { model.Filters.Add(new AddHeaderAttribute( "OtherPagesHeader", new string[] { "OtherPages Header Value" })); });
在OtherPages/Page1
中請求示例的 Page1 頁面,並檢查標頭以查看結果:
4.2 頁面應用模型約定
使用AddPageApplicationModelConvention創建並添加IPageApplicationModelConvention ,它在調用操作PageApplicationModel頁使用指定的名稱。示例演示瞭如何使用 AddPageApplicationModelConvention 將標頭 AboutHeader 添加到“About”頁面:
//頁面應用模型約定 options.Conventions.AddPageApplicationModelConvention("/Privacy", model => { model.Filters.Add(new AddHeaderAttribute( "PrivacyHeader", new string[] { "Privacy Header Value" })); });
請求示例的 Privacy頁面,並檢查標頭以查看結果:
4.3 配置篩選器
ConfigureFilter 可配置要應用的指定篩選器。 用戶可以實現篩選器類,但示例應用演示瞭如何在 Lambda 表達式中實現篩選器,該篩選器在後臺作為可返回篩選器的工廠實現:
options.Conventions.ConfigureFilter(model => { if (model.RelativePath.Contains("OtherPages/Page2")) { return new AddHeaderAttribute( "OtherPagesPage2Header", new string[] { "OtherPages/Page2 Header Value" }); } return new Pages.OtherPages.EmptyFilter(); });
public class EmptyFilter : IActionFilter { public void OnActionExecuting(ActionExecutingContext context) { // do something before the action executes } public void OnActionExecuted(ActionExecutedContext context) { // do something after the action executes } }
頁面應用模型用於檢查指向 OtherPages 文件夾中 Page2 頁面的段的相對路徑。 如果條件通過,則添加標頭。 如果不通過,則應用 EmptyFilter
。由於 Razor 頁面會忽略操作篩選器,因此,如果路徑不包含 OtherPages/Page2
,EmptyFilter
會按預期發出空操作指令。
在OtherPages/Page2中請求示例的 Page2 頁面,並檢查標頭以查看結果:
4.4 配置篩選器工廠
除了4.3的 Lambda 表達式配置篩選器。還可以對ConfigureFilter 配置指定的工廠,以將篩選器應用於所有 Razor 頁面。示例應用說明如何使用篩選器工廠將具有兩個值的標頭 FilterFactoryHeader 添加到應用的頁面:
options.Conventions.ConfigureFilter(new AddHeaderWithFactory());
public class AddHeaderWithFactory : IFilterFactory { // Implement IFilterFactory public IFilterMetadata CreateInstance(IServiceProvider serviceProvider) { return new AddHeaderFilter(); }/// <summary>
/// IResultFilter繼承了IFilterMetadata介面
/// </summary>
private class AddHeaderFilter : IResultFilter { public void OnResultExecuting(ResultExecutingContext context) { context.HttpContext.Response.Headers.Add( "FilterFactoryHeader", new string[] { "Filter Factory Header Value 1", "Filter Factory Header Value 2" }); } public void OnResultExecuted(ResultExecutedContext context) { } } public bool IsReusable { get { return false; } } }
在/About
中請求示例的“About
”頁面,並檢查標頭以查看結果:
五.替換預設的頁面應用模型
Razor 頁面使用 IPageApplicationModelProvider 介面創建 DefaultPageApplicationModelProvider。 用戶可以從預設模型提供程式繼承,以便為處理程式提供自己的實現邏輯。 預設實現是:“未命名的處理程式方法”和“預設已命名處理程式的約定方法。
5.1 預設的未命名處理程式方法
未命名處理程式方法是以:Http 謂詞為處理的程式方法,遵循以下約定:On<HTTP verb>[Async]
(追加 Async
是可選操作,但建議為非同步方法執行此操作)。主要的三個Http 謂詞:get、post、delete。
未命名處理程式方法 |
操作 |
OnGet/OnGetAsync |
初始化頁面狀態 |
OnPost/OnPostAsync |
處理 POST 請求。 |
OnDelete/OnDeleteAsync |
處理 DELETE 請求。 |
例如在index頁面,實現post提交,示例如下:
<form method="post" > <input type="submit" value="新增" class="btn btn-danger" asp-route-id="1" /> </form>
[HttpPost] public async Task<IActionResult> OnPostAsync(int id) { await SaveAsync(id); // RedirectToPageResult實現了IActionResult介面 RedirectToPageResult result = RedirectToPage(); return result; }
5.2 預設的已命名處理程式方法
由開發人員提供的處理程式方法,遵循的約定是: On<HTTP verb><handler name>[Async], 處理程式名稱出現在 Http 謂詞之後或者 Http 謂詞與 Async 之間。 例如,提交一個處理程式方法名為Message,那命名約定是OnPostMessage/OnPostMessageAsync。
<form method="post"> <input type="submit" value="消息提交" class="btn btn-danger" asp-route-id="1" asp-page-handler="Message" /> </form>
public async Task<IActionResult> OnPostMessageAsync(int id) { await SaveAsync(id); return RedirectToPage(); }
註意:OnPostMessageAsync上面不用加http謂詞。在頁面asp-page-handler必須指定後臺處理程式方法名。
5.3 自定義處理程式方法名稱
上面的處理程式方法都是需要按照預設約定,才能關聯起來。使用自定義處理程式可以讓用戶更改未命名和已命名的程式方法的命名方式。 假設:避免讓方法名稱以“On”開頭,並使用第一個分詞來確定 Http 謂詞,比如將DELETE、PUT 和 PATCH 的謂詞轉換為 POST。這樣程式可以提供下表所示的方法名稱。
處理程式方法 |
操作 |
Get |
初始化頁面狀態 |
Post/PostAsync |
處理 POST 請求 |
PostMessage/PostMessageAsync |
POST 消息 |
DeleteMessage/DeleteMessageAsync |
OST 消息以進行刪除 |
PutMessage/PutMessageAsync |
POST 消息以進行放置 |
若要建立此方案,請從 DefaultPageApplicationModelProvider 類繼承並重寫 CreateHandlerModel 方法,以提供自定義邏輯來解析 PageModel 處理程式名稱。 示例應用展示瞭如何在其 CustomPageApplicationModelProvider 類中執行此操作:
當CustomPageApplicationModelProvider類繼承DefaultPageApplicationModelProvider想重寫處理程式方法名稱時,vs提示錯誤:DefaultPageApplicationModelProvider不可訪問,因為它具有一定保護級別。保護級別如下圖所示:
在實際項目中,一般也不會自定義處理程式方法名稱,遵循既有的方法名約定都能滿足開發業務。這裡的實現以後在考慮吧。
參考文獻
官方資料:asp.net core routing