一.概述

  在上二篇中,主要是介绍了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框架路由(上)的更多相关文章

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

    三.页面路由操作约定 接着上篇讲asp.net core 系列 7 Razor框架路由.在上篇继续第三节 "页面路由操作约定" 的最后一小节 AddPageRoute . 3.3. ...

  2. asp.net core 系列 5 MVC框架路由(上)

    一. 概述 介绍asp.net core路由时,我初步想了下,分几篇来说明.  路由的知识点很多,参考了官方文档提取出一些重要的知识点来说.    在ASP.NET Core中是使用路由中间件来匹配传 ...

  3. asp.net core 系列 6 MVC框架路由(下)

    一.URL 生成 接着上篇讲MVC的路由,MVC 应用程序可以使用路由的 URL 生成功能,生成指向操作的 URL 链接. 生成 URL 可消除硬编码 URL,使代码更稳定.更易维护. 此部分重点介绍 ...

  4. asp.net core系列 39 Razor 介绍与详细示例

    原文:asp.net core系列 39 Razor 介绍与详细示例 一. Razor介绍 在使用ASP.NET Core Web开发时, ASP.NET Core MVC 提供了一个新特性Razor ...

  5. 【目录】asp.net core系列篇

    随笔分类 - asp.net core系列篇 asp.net core系列 68 Filter管道过滤器 摘要: 一.概述 本篇详细了解一下asp.net core filters,filter叫&q ...

  6. asp.net core系列 39 Web 应用Razor 介绍与详细示例

    一. Razor介绍 在使用ASP.NET Core Web开发时, ASP.NET Core MVC 提供了一个新特性Razor. 这样开发Web包括了MVC框架和Razor框架.对于Razor来说 ...

  7. 【asp.net core 系列】4. 更高更强的路由

    0. 前言 在之前我们介绍了请求通过路由寻找到控制器,以及控制器与视图的数据流转.那么,我们回过头来,再看看路由的一些其他用法. 1. 路由属性(Route Attribute) 按照英文的直接翻译, ...

  8. 【asp.net core 系列】2 控制器与路由的恩怨情仇

    0. 前言 在上一篇文章中,我们初步介绍了asp.net core,以及如何创建一个mvc项目.从这一篇开始,我将为大家展示asp.net core 的各种内容,并且尝试带领大家来挖掘其中的内在逻辑. ...

  9. asp.net core系列 40 Web 应用MVC 介绍与详细示例

    一. MVC介绍 MVC架构模式有助于实现关注点分离.视图和控制器均依赖于模型. 但是,模型既不依赖于视图,也不依赖于控制器. 这是分离的一个关键优势. 这种分离允许模型独立于可视化展示进行构建和测试 ...

随机推荐

  1. java使用Jedis远程访问CentOs7linux时出现拒绝连接的错误

    使用Jedis出现Connection refused的解决方案 当我们利用Jedis操作服务器的Redis数据库时,需要先将远程服务器的端口(默认端口是6379)开放,命令如下:   #/sbin/ ...

  2. 【redis】在dotnet core下的redis的使用

    1.Install-Package Microsoft.Extensions.Caching.Redis -Version 2.2.0 2.注入 services.AddDistributedRedi ...

  3. hdu 2005 java

    题意: 输入数据格式为YYYY/MM/DD,对于每组输入数据,输出一行,表示该日期是该年的第几天. 思路: 使用Calendar.DAY_OF_YEAR import java.text.ParseE ...

  4. Centos7使用kubeadm部署kubernetes-1.11.2

    1.安装方式 1.  传统方式,以下组件全部运行在系统层面(yum或者rpm包),都为系统级守护进程 2.  kubeadm方式,master和node上的组件全部运行为pod容器,k8s也为pod ...

  5. [Ubuntu]pkg-config和ldconfig

    转载自->这里 我们知道,linux编译源码包基本步骤无非是:configure,make,make install三部曲:configure过程中可能会遇到无法找到某些头文件和动态库:原因有两 ...

  6. linux去除\r(window中编辑的文本)

    vim -b file 二进制贷款文件:%s/^M//g         # 注意这里使用Ctrl+V+M输入^M 上面的方法我就不行,但是下面的可以: 如果不行可以使用 :%s/\r//

  7. angular.uppercase()

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  8. Java-IO流之转换流的使用和编码与解码原理

    一.理论: 1.字符流和字节流区别是什么? 字符流=字节流+编码集,在实际读取的时候其实字符流还是按照字节来读取,但是会更具编码集进行查找编码集字典解析相应的字节,使得一次读取出一个字符: 2.什么是 ...

  9. position属性sticky和fixed的区别比较

    position属性之fixed fixed总是以body为定位时的对象,总是根据浏览器窗口来进行元素的定位,通过left,right,top,bottom属性进行定位. <!DOCTYPE h ...

  10. 文件操作,列表实例NiceHexSpiral

    fr = open('letter.txt',mode='r',encoding='utf-8') plaincode = fr.read() print('明文:' + plaincode) pri ...