asp.net core 系列 7 Razor框架路由(上)
一.概述
在上二篇中,主要是介绍了asp.net core mvc中路由的使用,这篇继续介绍路由在ASP.NET Core Razor中的使用。Razor Pages应该使用默认的传统路由,从应用程序的Pages文件夹中提供命令资源。还可以使用其他约定来自定义 Razor Pages 路由行为。
在ASP.NET Core MVC 中是使用路由中间件来匹配传入请求的 URL 并将它们映射到操作(action)。而ASP.NET Core Razor使用页面路由和应用模型提供程序约定,来控制 Razor 页面应用中的页面路由、发现和处理。
使用AddRazorPagesOptions 扩展方法向 Startup 类中服务集合的 AddMvc 服务中添加和配置 Razor 页面约定。
- services.AddMvc()
- .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
- .AddRazorPagesOptions(options=> {
- //添加razor页面路由和应用模型约定
- //options.Conventions.Add();
- });
在ASP.NET Core 的 Razor框架页面中,路由和应用的约定有四大类。都需要实现IPageConvention接口。在MVC框架下路由需要实现IRouteBuilder接口。
(1) 模型约定 Conventions.Add
通过Conventions.Add添加的模型约定(Model conventions)。作用是:将路由模板和标头(page header)添加到应用的页面。模型约定有三种实现的接口IPageRouteModelConvention(路由模型约定)、IPageApplicationModelConvention(应用模型约定)、IPageHandlerModelConvention(处理程序模型约定)。
(2) 页面路由操作约定 Page route action conventions
通过页面路由操作约定。作用是:可以将路由模板添加到某个文件夹中的页面以及单个页面。AddFolderRouteModelConvention(文件夹路由模型约定)、AddPageRouteModelConvention(页面路由模型约定)AddPageRoute(配置页面路由)
(3) 页面模型操作约定 Page model action conventions
通过页面模型操作约定。作用是:可以将标头添加到某个文件夹中的多个页面,将标头添加到单个页面,以及配置筛选器工厂以将标头添加到应用的页面
AddFolderApplicationModelConvention(文件夹应用模型约定) AddPageApplicationModelConvention(页面应用模型约定) ConfigureFilter(配置筛选器)
(4) 默认页面应用模型提供程序 Default page app model provider
用户可以从默认模型提供程序继承,以便为处理程序发现和处理提供自己的实现逻辑 。
二. 模型约定
为IPageConvention添加委托,以添加应用于 Razor 页面的模型约定。
2.1 IPageRouteModelConvention
将路由模型约定添加到所有页面。使用约定创建IPageRouteModelConvention并将其添加到IPageConvention实例集合中,这些实例将在页面路由模型构造过程中应用。下面示例应用将 {globalTemplate?} 路由模板添加到应用中的所有页面。
- /// <summary>
- /// 只在程序启动时调用(每页面路由对应执行一次apply)
- /// </summary>
- public class GlobalTemplatePageRouteModelConvention : IPageRouteModelConvention
- {
- ///<summary>
- ///运用到所有页面路由模型中,制定页面路由模板,比如访问index页。
- ///路由模板可以是/index 也可以是/index/{可选参数}
- ///</summary>
- ///<param name="model"></param>
- public void Apply(PageRouteModel model)
- {
- var selectorCount = model.Selectors.Count;
- for (var i = ; i < selectorCount; i++)
- {
- var selector = model.Selectors[i];
- model.Selectors.Add(new SelectorModel
- {
- AttributeRouteModel = new AttributeRouteModel
- {
- //执行路由顺序
- Order = ,
- //页面路由模板
- Template = AttributeRouteModel.CombineTemplates(selector.AttributeRouteModel.Template,"{globalTemplate?}")
- }
- });
- }
- }
- }
将 MVC 添加到Startup.ConfigureServices中的服务集合时,会添加 Razor 页面选项,例如:添加上面的约定。
- services.AddMvc()
- .AddRazorPagesOptions(options =>
- {
- options.Conventions.Add(new GlobalTemplatePageRouteModelConvention());
- })
- .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
在about页绑定 @RouteData.Values["globalTemplate"]。如果在浏览器访问: /about/globalRouteValue时,页面显示:route data for'globalTemplate'wasprovided:globalRouteValue。
在上面案例的路由模型约定的PageRouteModel实例中,在调试下查看about的路由规则生成如下: model.Selectors[1].AttributeRouteModel.Template的值为:
About/{globalTemplate?}
2.2 IPageApplicationModelConvention
将应用模型约定添加到所有页面。使用约定创建IPageApplicationModelConvention并将其添加到IPageConvention实例集合中,这些实例将在页面应用模型构造过程中应用。
为了演示此约定,示例应用包含了一个 AddHeaderAttribute
类。 类构造函数采用 name
字符串和 values
字符串数组。 将在其 OnResultExecuting
方法中使用这些值来设置响应标头。使用 AddHeaderAttribute
类将标头 GlobalHeader
添加到应用中的所有页面。
- ///<summary>
- ///页面加载时调用(每一个路由地址)
- ///</summary>
- public class GlobalHeaderPageApplicationModelConvention : IPageApplicationModelConvention
- {
- public void Apply(PageApplicationModel model)
- {
- model.Filters.Add(new AddHeaderAttribute(
- "GlobalHeader", new string[] { "Global Header Value" }));
- }
- }
- public class AddHeaderAttribute : ResultFilterAttribute
- {
- private readonly string _name;
- private readonly string[] _values;
- public AddHeaderAttribute(string name, string[] values)
- {
- _name = name;
- _values = values;
- }
- public override void OnResultExecuting(ResultExecutingContext context)
- {
- context.HttpContext.Response.Headers.Add(_name, _values);
- base.OnResultExecuting(context);
- }
- }
- services.AddMvc()
- .AddRazorPagesOptions(options =>
- {
- options.Conventions.Add(new GlobalTemplatePageRouteModelConvention());
- options.Conventions.Add(new GlobalHeaderPageApplicationModelConvention());
- })
- .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
在 /About
中请求示例的“关于”页面,并检查标头以查看结果:
2.3 IPageHandlerModelConvention
将处理程序模型约定添加到的所有页面。使用约定创建IPageHandlerModelConvention并将其添加到IPageConvention实例集合中,这些实例将在页面处理程序模型构造过程中应用。
- public class GlobalPageHandlerModelConvention : IPageHandlerModelConvention
- {
- //页面加载时调用(每一个路由地址),在IPageApplicationModelConvention约定之后执行
- public void Apply(PageHandlerModel model)
- {
- //目前还不清楚能做什么
- }
- }
- services.AddMvc()
- .AddRazorPagesOptions(options =>
- {
- options.Conventions.Add(new GlobalTemplatePageRouteModelConvention());
- options.Conventions.Add(new GlobalHeaderPageApplicationModelConvention());
- options.Conventions.Add(new GlobalPageHandlerModelConvention());
- })
- .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
三. 页面路由操作约定
默认路由模型提供程序派生自IPageRouteModelProvider,可调用旨在为页面路由配置提供扩展点的约定。
3.1 AddFolderRouteModelConvention
使用AddFolderRouteModelConvention创建并添加IPageRouteModelConvention,后者可以为指定文件夹下的所有页面调用PageRouteModel上的操作。示例应用使用
AddFolderRouteModelConvention
将 {otherPagesTemplate?}
路由模板添加到 OtherPages 文件夹中的页面:
- options.Conventions.AddFolderRouteModelConvention("/OtherPages", model =>
- {
- //OtherPages文件夹下的页面,都用此路由模板。
- var selectorCount = model.Selectors.Count;
- for (var i = ; i < selectorCount; i++)
- {
- var selector = model.Selectors[i];
- model.Selectors.Add(new SelectorModel
- {
- AttributeRouteModel = new AttributeRouteModel
- {
- //用于处理路由匹配,指定路由处理顺序。按顺序处理的路由 (-1、 0、 1、 2、 … n)
- Order = ,
- Template = AttributeRouteModel.CombineTemplates
- (selector.AttributeRouteModel.Template,"{otherPagesTemplate?}")
- }
- });
- }
- });
这里将AttributeRouteModel的 Order 属性设置为 2。在第一个路由数据值时(如:/page1/RouteDataValue,这里的RouteDataValue就是第一个路由数据值),可以保证之前模板{globalTemplate?}分配到优先级。
当globalTemplate路由模板Order=1,otherPagesTemplate路由模板Order=2时。在浏览器输入 :/OtherPages/Page1/RouteDataValue。路由值由globalTemplate模板取出。
- RouteData.Values["otherPagesTemplate"]
- null
- RouteData.Values["globalTemplate"]
- "RouteDataValue"
3.2 AddPageRouteModelConvention
使用AddPageRouteModelConvention创建并添加IPageRouteModelConvention,后者可以为具有指定名称的页面调用PageRouteModel上的操作。
示例应用使用AddPageRouteModelConvention将 {aboutTemplate?} 路由模板添加到“About”页面:
- options.Conventions.AddPageRouteModelConvention("/About", model =>
- {
- //About页面,用此路由模板。
- var selectorCount = model.Selectors.Count;
- for (var i = ; i < selectorCount; i++)
- {
- var selector = model.Selectors[i];
- model.Selectors.Add(new SelectorModel
- {
- AttributeRouteModel = new AttributeRouteModel
- {
- Order = ,
- Template = AttributeRouteModel.CombineTemplates
- (selector.AttributeRouteModel.Template, "{aboutTemplate?}")
- }
- });
- }
- });
这个功能就不在演示,功能与示例3.1相同,一个作用于文件夹下的所有pages页面,一个作用于指定某个page页面。重点关注三点:1是路由作用域,2是order路由顺序,3是定义好Template路由规则。
参考文献
官方资料:asp.net core routing
asp.net core 系列 7 Razor框架路由(上)的更多相关文章
- asp.net core 系列 8 Razor框架路由(下)
三.页面路由操作约定 接着上篇讲asp.net core 系列 7 Razor框架路由.在上篇继续第三节 "页面路由操作约定" 的最后一小节 AddPageRoute . 3.3. ...
- asp.net core 系列 5 MVC框架路由(上)
一. 概述 介绍asp.net core路由时,我初步想了下,分几篇来说明. 路由的知识点很多,参考了官方文档提取出一些重要的知识点来说. 在ASP.NET Core中是使用路由中间件来匹配传 ...
- asp.net core 系列 6 MVC框架路由(下)
一.URL 生成 接着上篇讲MVC的路由,MVC 应用程序可以使用路由的 URL 生成功能,生成指向操作的 URL 链接. 生成 URL 可消除硬编码 URL,使代码更稳定.更易维护. 此部分重点介绍 ...
- asp.net core系列 39 Razor 介绍与详细示例
原文:asp.net core系列 39 Razor 介绍与详细示例 一. Razor介绍 在使用ASP.NET Core Web开发时, ASP.NET Core MVC 提供了一个新特性Razor ...
- 【目录】asp.net core系列篇
随笔分类 - asp.net core系列篇 asp.net core系列 68 Filter管道过滤器 摘要: 一.概述 本篇详细了解一下asp.net core filters,filter叫&q ...
- asp.net core系列 39 Web 应用Razor 介绍与详细示例
一. Razor介绍 在使用ASP.NET Core Web开发时, ASP.NET Core MVC 提供了一个新特性Razor. 这样开发Web包括了MVC框架和Razor框架.对于Razor来说 ...
- 【asp.net core 系列】4. 更高更强的路由
0. 前言 在之前我们介绍了请求通过路由寻找到控制器,以及控制器与视图的数据流转.那么,我们回过头来,再看看路由的一些其他用法. 1. 路由属性(Route Attribute) 按照英文的直接翻译, ...
- 【asp.net core 系列】2 控制器与路由的恩怨情仇
0. 前言 在上一篇文章中,我们初步介绍了asp.net core,以及如何创建一个mvc项目.从这一篇开始,我将为大家展示asp.net core 的各种内容,并且尝试带领大家来挖掘其中的内在逻辑. ...
- asp.net core系列 40 Web 应用MVC 介绍与详细示例
一. MVC介绍 MVC架构模式有助于实现关注点分离.视图和控制器均依赖于模型. 但是,模型既不依赖于视图,也不依赖于控制器. 这是分离的一个关键优势. 这种分离允许模型独立于可视化展示进行构建和测试 ...
随机推荐
- windows与linux多线程对比
一.创建线程 1>windows HANDLE aThread[MAX_THREAD]; 函数原型: HANDLE WINAPI CreateThread( _In_opt_ LPSECUR ...
- Oracle ctl模版
将txt数据装载到数据库 数据无”” LOAD DATA CHARACTER-SET ZHS16GBK truncate into table a FIELDS TERMINATED BY ‘,’ T ...
- 如何使用$.each()与$().each()以及他们的区别
1.首先,说下$.each(Arry/Object,function(index,val){ //index表示下标,val表示下标对应的值 }) 下面是使用$.each()的几种类型,其中arr2与 ...
- IaaS,PaaS和SaaS
云计算的三种服务模式:IaaS,PaaS和SaaS IaaS: Infrastructure-as-a-Service(基础设施即服务)是第一层. PaaS: Platform-as-a-Servic ...
- vue 时间戳 转 日期
<text style="padding-right: 10px; color: #333; font-size: 28px" slot="value"& ...
- PLC不能初始化问题
检索COM 类工厂中 CLSID 为 <28e68f9a-8d75-11d1-8dc3-3c302a000000> 的组件时失败,原因是出现以下错误: 80040154 解决方案: Win ...
- 搭建 RTMP 服务器
主要步骤 具体步骤 FAQ docker 搭建版 参考 主要步骤 下载 nginx 的 rtmp 模块 编译nginx,带 hls,rtmp 配置 nginx.conf,设置 rtmp 的推流文件路径 ...
- python爬虫第六天
今天继续学习一些实战爬虫 链接爬虫实战 要求:把一个网页里所有的链接地址提取出来 思路:(1)确定爬取的入口链接 (2)构建提取链接的正则表 ...
- js拼接字符串后swiper不能动的解决方案
swiper的配置一定要放在拼接字符串之后,紧随其后,如果放在其他的位置,swiper是不识别HTML的.
- Python爬虫(2):urllib库
爬虫常用库urllib 注:运行环境为PyCharm urllib是Python3内置的HTTP请求库 urllib.request:请求模块 urllib.error:异常处理模块 urllib.p ...