asp.net core 系列 8 Razor框架路由(下)


三.頁面路由操作約定

   接着上篇講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/Page2EmptyFilter 會按預期發出空操作指令。

    在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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM