完整的流程
对于我们创建的这个迷你版的ASP.NET MVC框架来说,虽然很多细节被直接忽略掉,但是它基本上能够展现整个ASP.NET MVC框架的全貌,支持这个开发框架的核心对象可以说一个不少。接下来我们对通过这个模拟框架展现出来的ASP.NET MVC针对请求的处理流程作一个简单的概括。
由于UrlRoutingModule这个HttpModule被注册到Web应用中,所以对于每个抵达的请求来说,当代表当前应用的HttpApplication对象的PostResolveRequestCache事件被触发的时候,UrlRoutingModule会利用RouteTable表示的路由表(实际上RouteTable的静态属性Routes返回的RouteDictionary对象代表这个路由表)针对当前请求实施路由解析。
具体来说,URLRoutingModule会调用代表路由表的RouteDictionary对象的GetRouteData方法,如果定义在某个Route对象上的路由规则与当前请求相匹配,那么该方法执行结束之后会返回一个RouteData对象,包含目标Controller和Action名称的路由变量被包含在这个RouteData对象之中。
接下来UrlRoutingModule通过RouteData对象的RouteHandler属性得到匹配Route对象采用的RouteHandler对象,在默认情况下这是一个MvcRouteHandler对象,URLRoutingModule随后会调用这个MvcRouteHandler对象的GetHttpHandler方法得到一个HttpHandler对象。对于MvcRouteHandler来说,他的GetHttpHandler方法具体返回的是一个MvcHandler对象。UrlRoutingModule随之调用当前HTTP上下文的MapHttpHandler方法对得到的HttpHandler对象实施映射,那么此HttpHandler将最终接管当前请求的处理。
对于MvcHandler来说,当它被用来处理当前请求的时候,他会利用RouteData对象得到目标Controller的名称,并借助于注册的ControllerFactory来激活对应的Controller对象。目标。Controller被激活之后,它的Execute方法被MvcHandler调用。
如果被激活的Controller对象的类型是ControllerBase的子类,当它的Execute方法被执行的时候,它会调用ActionInvoker对象的InvokeAction方法来执行Action方法并对当前请求予以响应。默认采用的ActionInvoker是一个ControllerActionInvoker对象,当它的InvokeAction方法被执行的时候,他利用注册的ModelBinder采用Model绑定的方式生成目标Action方法的参数列表,并利用ActionExecute对象以“表达式树”的方式执行目标Action方法。
目标Action方法执行之后总是会返回一个ActionResult(对于返回类型不是ActionResult的Action方法来说,ASP.NET MVC总是会将执行的结果转换成一个ActionResult对象),ControllerActionInvoker会通过执行此ActionResult对象来对请求作最终响应。