接着上篇讲asp.net core 系列 7 Razor框架路由。在上篇继续第三节 "页面路由操做约定" 的最后一小节 AddPageRoute 。html
使用 AddPageRoute 配置路由,该路由与指定页面关联, 使用指定的路由生成页面连接。 AddPageRoute 使用 AddPageRouteModelConvention 创建路由。框架
示例应用为 Privacy.cshtml 建立指向 /ThePrivacyPage 的路由:asp.net
options.Conventions.AddPageRoute("/Privacy", "ThePrivacyPage/{text?}");
能够经过原有 /
Privacy默认路由访问“Privacy”页面。http://localhost:60397/Privacy异步
也能够经过上面自定义的页面路由访问Privacy页面。 http://localhost:60397/ThePrivacyPageasync
示例应用的“Privacy”页面自定义路由容许使用可选的 text
路由段 ({text?}
)。 该页面还在其 @page
指令中包含此可选段,以便访问者在 /
Privacy 路由中访问该页面。在呈现的页面中,为Privacy连接生成的 URL 显示了已更新的路由,以下所示:ide
实现 IPageApplicationModelProvider 的默认页面模型提供程序可调用约定,这些约定旨在为页面模型配置提供扩展点。 在生成和修改页面发现及处理方案时,可以使用这些约定。这里继续使用上篇讲的 AddHeaderAttribute
类(一个ResultFilterAttribute)来应用响应标头。post
使用 AddFolderApplicationModelConvention 建立并添加 IPageApplicationModelConvention,后者能够为指定文件夹下的全部页面调用 PageApplicationModel 实例上的操做。 示例演示了如何使用 AddFolderApplicationModelConvention
将标头 OtherPagesHeader
添加到应用的OtherPages 文件夹内的页面:spa
//文件夹应用模型约定 options.Conventions.AddFolderApplicationModelConvention("/OtherPages", model => { model.Filters.Add(new AddHeaderAttribute( "OtherPagesHeader", new string[] { "OtherPages Header Value" })); });
在OtherPages/Page1
中请求示例的 Page1 页面,并检查标头以查看结果:.net
使用AddPageApplicationModelConvention建立并添加IPageApplicationModelConvention ,它在调用操做PageApplicationModel页使用指定的名称。示例演示了如何使用 AddPageApplicationModelConvention 将标头 AboutHeader 添加到“About”页面:3d
//页面应用模型约定 options.Conventions.AddPageApplicationModelConvention("/Privacy", model => { model.Filters.Add(new AddHeaderAttribute( "PrivacyHeader", new string[] { "Privacy Header Value" })); });
请求示例的 Privacy页面,并检查标头以查看结果:
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.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
”页面,并检查标头以查看结果:
未命名处理程序方法是以: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; }
由开发人员提供的处理程序方法,遵循的约定是: 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必须指定后台处理程序方法名。
上面的处理程序方法都是须要按照默认约定,才能关联起来。使用自定义处理程序可让用户更改未命名和已命名的程序方法的命名方式。 假设:避免让方法名称以“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