先看路由模块的PostResolveRequestCache事件中被触发的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
|
这 个方法做的工作还是比较清晰的,首先从RouteCollection中获得RouteData,从RouteData中获得RouteHandler, 从RouteHandler获得httpHandler,最后调用RemapHandler将控制权交给httpHandler。 UrlRoutingModule是System.Web中的通用的路由模块,并不仅限于给ASP.NET MVC使用,这里处理的今本都是针对抽象接口来处理的。后文会介绍ASP.NET MVC是如何利用这个模块实现了URL到controller/action的映射的。
RouteCollection是一张路由表,里面 包括了很多路由规则(RouteBase),RouteData则是解析好的路由,里面包括了Key-Value对的路由信息,一个 routehandler。RouteCollection的GetRouteData方法,是找到符合当前请求的路由规则的RouteData,其内部 实现就是遍历所有的路由规则,调用RouteBase的GetRouteData方法,返回第一个非空的RouteData。IRouteHandler 只有一个方法,
1 2 3 4 |
|
但 是他是从路由模块完成最重要的工作之一,等到其他模块执行完毕之后,将由这个IHttpHandler(如果其他模块没有更改这个handler)来完成 接下来的请求。得到合适的HttpHandler之后,调用了HttpContext的RemapHandler方法,这个方法的核心是
1 |
|
此时尚没有真正的转交控制权,当前的handler还是global.asax中的类,在上文中有介绍到在初始化一个请求的时候,由一个StepManager来初始化需要触发的step,其中有:
1 |
|
因此在MapRequestHandler的时候,会触发MaterializeHandlerExecutionStep的Execute方法,其中主要的代码是:
1 2 3 4 5 6 |
|
在MapRequestHandler之后调用RemapHandler会导致异常,原因是改变handler的时机是在MapRequestHandler。
下 面看ASP.MVC框架是如何使用这个routing module的。MVC在RouteCollectionExtensions这个类中定义了一系列扩展方法,扩展了原有的 RouteCollection类。RouteCollection类是支持ASP.NET Webform的路由模块,可以用MapPageRoute方法将url映射到aspx文件上。RouteCollectionExtensions的核 心方法是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
注意Route构造函数中的第二个参数,这是一个MvcRouteHandler,这个handler也就是RouteData中的RouteHandler的值,其实现为:
1 2 3 4 |
|
暂时忽略这里的SessionStateBehavior,可以看到最终的httpHandler是MvcHandler。
综 上,routing module在PostResolveRequestCache被触发,获得RouteCollection中的 Route(System.Web.Routing),解析Route数据获得RouteData,MVC框架设置RouteData中的 RouteHandler为MvcRouteHandler,MvcRouteHandler的GetHttpHandler方法返回的是一个 MvcHandler,这个handler最终在MapRequestHandler事件触发的时候接过request处理流程,开始处理请求,它将利用 RouteData中解析好的值去触发controller/action,这个下文再介绍。ASP.NET MVC的路由模块主要是用的.NET中的System.Web.Routing.Route类来实现的,Route类的主要工作是解析路由规则,得到一个 Key-Value对的序列。这是一个单纯而又复杂的过程,这里不分析其实现。
发表回复