学习ASP.NET MVC5框架揭秘笔记-ASP.NET MVC路由(四)

2.2.4基于Area的路由映射

对于一个较大规模的Web应用,我们可以从功能上通过Area将其划分为较小的单元。每个Area相当于一个独立的子系统,它们具有一套包含Models、Views和Controller在内的目录结构和配置文件。一般来说,每个Area具有各自的路由规则(路由模板上一般会包含Area的名称),而基于Area的路由映射通过AreaRegistration类型进行注册。

1.AreaRegistration与AreaRegistrationContext

针对Area的路由通过AreaRegistration来注册。如下面的代码所示,AreaRegistration是一个抽象类,它的抽象只读属性AreaName返回当前Area的名称,而抽象方法RegisterArea用于实现基于当前Area的路由注册。

public abstract class AreaRegistration
{
public static void RegisterAllAreas();
public static void RegisterAllAreas(object state);
public abstract string AreaName { get; };
public abstract void RegisterArea(System.Web.Mvc.AreaRegistrationContext context);
}

AreaRegistration定义了两个抽象的静态RegisterAllAreas方法重载,参数state表示传递给具体AreaRegistration的数据。当RegisterAllArea方法执行的时候,所有被当前Web应用直接或间接引用的程序集会被加载(如果尚未被加载),ASP.NET MVC会从这些程序集中解析出所有继承自AreaRegistration的类型,并通过反射创建相应的AreaRegistration对象。针对每个被创建出来的AreaRegistration对象,一个作为Area注册上下文的AreaRegistrationContext对象会被创建出来,它被作为参数调用这些AreaRegistration对象的RegisterArea方法进行针对相应Area的路由注册。

如下面的代码片段所示,AreaRegistrationContext的只读属性AreaName表示Area的名称,属性Routes是一个代表路由表的RouteCollection对象,而State是一个用户自定义对象,他们均通过构造函数进行初始化。具体来说,AreaRegistrationContext对象是在调用AreaRegistration的静态方法RegisterAllAreas时针对创建出来的AreaRegistration对象构建的,其AreaName来源于当前AreaRegistration对象的同名属性,Routes则对应着RouteTable的静态属性Routes所表示的全局路由表。调用RegisterAllAreas方法指定的参数state将被作为调用AreaRegistrationContext构造函数的同名参数。

public class AreaRegistrationContext
{
public AreaRegistrationContext(string areaName,RouteCollection routes, object state);
public AreaRegistrationContext(string areaName,RouteCollection routes);
public Route MapRoute(string name, string url, object defaults, object constraints, string[] namespaces);
public Route MapRoute(string name, string url, object defaults, string[] namespaces);
public Route MapRoute(string name, string url, string[] namespaces);
public Route MapRoute(string name, string url, object defaults, object constraints);
public Route MapRoute(string name, string url, object defaults);
public Route MapRoute(string name, string url);
public string AreaName { get; }
public ICollection<string> Namespaces { get; }
public RouteCollection Routes { get; }
public object State { get; }
}

AreaRegistrationContext的只读属性Namespaces表示一组需要优先匹配的命名空间(当多个同名的Controller类型定义在不同的命名空间的时候,定义在这些命名空间的Controller类型会被优先选用)。当针对某个具体AreaRegistration的AreaRegistrationContext对象被创建的时候,如果AreaRegistration类型定义在某个命名空间(比如“Artech.Controllers”),则在这个命名空间基础上添加“.*”后缀生成的字符串(比如“Artech.Controllers.*”)会被添加到Namespaces集合中。换言之,对于多个定义在不同命名空间中的同名Controller类型,会优先选择包含在当前AreaRegistration所在命名空间下的Controller。

AreaRegistrationContext定义了一系列的MapRoute方法进行路由注册,方法的使用及参数的含义与RouteCollection类的同名扩展方法一致。在这里需要特别指出的是,如果MapRoute方法没有指定命名空间,通过属性Namespaces表示的命名空间列表会被使用;反之,该属性中包含的命名空间会被直接忽略。

当我们通过Visual Stdio的ASP.NET MVC项目模板创建一个Web应用的时候,在Global.asax文件中会生成类似如下的代码,在这里通过调用AreaRegistration的静态方法RegisterAllAreas实现对所有Area的注册。也就是说,针对所有Area的注册发生在Web应用启动的时候。

protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
//其他操作
}
时间: 2024-10-19 10:21:12

学习ASP.NET MVC5框架揭秘笔记-ASP.NET MVC路由(四)的相关文章

学习ASP.NET MVC5框架揭秘笔记-ASP.NET MVC路由(一)

2.2ASP.NET MVC路由 ASP.NET的路由系统旨在通过注册路由模板与物理文件路径之间的映射进而实现请求地址与文件路径之间的分离,但对于ASP.NET MVC应用来说,请求的目标不再是一个具体的物理文件,而是定义在某个Controller类型中的Action方法.出于自身路由特点的需要,ASP.NET MVC对ASP.NET路由系统进行了相应的扩展. 2.2.1路由映射 通过前面的介绍我们知道,RouteTable的静态属性Routes返回的RouteCollection对象代表了针对

学习ASP.NET MVC5框架揭秘笔记-ASP.NET路由(二)

实例演示:通过路由实现请求地址与.aspx页面的映射 我们创建一个简单的ASP.NET Web Forms应用,并采用一套独立于.aspx文件路径的URL来访问对应的Web页面,两者之间的映射通过路由来实现,我们依然沿用员工管理的场景. 首先我们将员工的所有信息(ID.姓名.性别.出生日期和所在部门)定义在如下所示的Employee类型中,然后定义一个EmployeeRepository类型来维护员工列表的数据.简单起见,员工列表通过静态字段employees表示.EmployeeReposit

学习ASP.NET MVC5框架揭秘笔记-ASP.NET MVC是如何运行的(四)

Action的执行 作为Controller的基类ControllerBase,它的Execute方法主要作用在于执行目标Action方法.如果目标Action方法返回一个ActionResult对象,它还需要执行该对象来对当前请求予以响应.在ASP.NET MVC框架中,两者的执行是通过一个叫做ActionInvoker的对象来完成的. 1.ActionInvoker 我们同样为ActionInvoker定义了一个借口IActionInvoker.如下所示.该接口定义了唯一的方法InvokeA

学习ASP.NET MVC5框架揭秘笔记-ASP.NET MVC是如何运行的(一)

ASP.NET MVC是如何运行的 ASP.NET由于采用了管道式设计,所以具有很好的扩展性,整个ASP.NET MVC应用框架就是通过扩展ASP.NET实现的.通过上面对ASP.NET管道设计的介绍我们知道,ASP.NET 的扩展点主要体现在HttpModule和HttpHandler这两个核心组件之上,整个ASP.NET MVC框架就是通过自定义的HttpModule和HttpHandler建立起来的. 接下来我们通过自定义组件来模拟ASP.NET MVC的运行原理. 1.4.1建立在迷你版

学习ASP.NET MVC5框架揭秘笔记-ASP.NET MVC路由(五)

2.AreaRegistration的缓存 Area的注册(主要是基于Area的路由映射注册)通过具体的AreaRegistration来完成.在应用启动的时候,ASP.NET MVC会遍历通过调用BuildManager的静态方法GetReferencedAssemblies得到的程序集列表,并从中找到所有AreaRegistration类型.如果一个应用涉及太多的程序集,则这个过程可能会耗费很多时间.为了提高性能,ASP.NET MVC会对解析出来的所有AreaRegistration类型列

学习ASP.NET MVC5框架揭秘笔记-ASP.NET MVC是如何运行的(三)

Controller的激活 ASP.NET MVC的路由系统通过注册的路由表对当前HTTP请求实施路由解析,从而得到一个用于封装路由数据的RouteData对象,这个过程是通过自定义的UrlRoutingModule对HttpApplication的PostResolveRequestCache事件进行注册实现的.由于得到的RouteData对象中已经包含了目标Controller的名称,我们需要根据该名称激活对应的Controller对象. 1.MvcRouteHandler 通过前面的介绍我

学习ASP.NET MVC5框架揭秘笔记-ASP.NET MVC是如何运行的(五)

完整的流程 对于我们创建的这个迷你版的ASP.NET MVC框架来说,虽然很多细节被直接忽略掉,但是它基本上能够展现整个ASP.NET MVC框架的全貌,支持这个开发框架的核心对象可以说一个不少.接下来我们对通过这个模拟框架展现出来的ASP.NET MVC针对请求的处理流程作一个简单的概括. 由于UrlRoutingModule这个HttpModule被注册到Web应用中,所以对于每个抵达的请求来说,当代表当前应用的HttpApplication对象的PostResolveRequestCach

学习ASP.NET MVC5框架揭秘笔记-ASP.NET MVC是如何运行的(二)

路由 对于一个ASP.NET MVC应用来说,针对HTTP请求的处理实现在目标Controller类型的某个Action,每个HTTP请求不在像ASP.NET Web Forms应用一样是针对一个物理文件,而是针对某个Controller的某个Action方法.目标Controller和Action的名称由HTTP请求的URL来决定,当ASP.NET MVC接收到抵达的请求后,其首要任务就是通过当前HTTP请求解析得到目标Controller和Action的名称,这个过程是通过ASP.NET M

学习ASP.NET MVC5框架揭秘笔记-ASP.NET MVC路由(二)

2.2.2 路由注册 ASP.NET MVC通过调用代表全局路由表的RouteCollection对象的扩展方法MapRoute进行路由注册.我们来进行一个简单的实例演示.我们依然沿用之前关于获取天气信息的路由模板,看看通过这种方式注册的Route对象针对匹配的请求将返回怎样一个RouteData对象. 我们创建一个空的ASP.NET Web程序,并手动添加"System.Web.Mvc.dll"和"System.Web.WebPages.Razor.dll"的引用

学习ASP.NET MVC5框架揭秘笔记-ASP.NET MVC路由(三)

2.2.3缺省URL参数 当通过VisualStudio的ASP.NET MVC项目模板创建一个Web应用后,它会为我们注册如下一个模板为"{controller}/{action}/{id}"的默认Route对象.3个路由模板均有相应额默认值.但是变量名为id的默认值为URLParameter.Optional.按照字面的意思,我们将其称为可缺省URL参数.那么将路由变量的默认值进行如此设置与设置一个具体的默认值有什么区别呢? routes.MapRoute( name: "