在Add方法的最后需要传一个IRouteHandler的对象,我们上文定义过一个MvcRouteHandler去实现了IRouteHandler,这个MvcRouteHandler在这里就派上用场了,原来我们的RouteHandler是可以自定义的。就是因为这里配置过这个,所以在GetRouteData()方法里面,就将MvcRouteHandler对象给了routeData对象的RouteHandler属性,终于知道这里的MvcRouteHandler是如何过来的了。这里可配置IRouteHandler也说明了MVC原理的灵活性,我们可以自定义RouteHandler,然后再IRouteHandler接口的GetHttpHandler()方法里面自定义处理当前请求的HttpHandler。
(3) RequestContext requestContext = new RequestContext(context, routeData);context.Request.RequestContext = requestContext; 这两句看上去不起眼,就是封装了一个RequestContext对象,然后将它给到了当前上下文的Request.RequestContext。实际上,这里非常重要,因为这个requestContext对象包含了我们当前请求的路由信息,后面MvcHandler里面需要从这里取到当前请求的控制器和Action的名称,待会看了后面的代码,你会更加清晰。
(4)再来看 IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext); 这一句
上文注释(2) 里面说了,routeHandler对象实际上是一个MvcRouteHandler对象,当它调用GetHttpHandler(),看下定义即可明白:
public class MvcRouteHandler:IRouteHandler { public System.Web.IHttpHandler GetHttpHandler(RequestContext requestContext) { return new MvcHandler(); } }
这里就是返回了一个MvcHandler,用来处理Http请求。
(5) context.RemapHandler(httpHandler); 这一句自然不必多说,请当前拦截到的请求交给MvcHandler的ProcessRequest方法处理,这一句执行完成之后,请求便转入到MvcHandler的ProcessRequest方法里面。纵观上述几个过程,可以说是一环扣一环,每一句都有它的意义所在,最后封装完成之后,真正处理请求还是在MvcHandler里面。接下来我们来看看ProcessRequest里面的代码。
(6)下面我们来看看MvcHandler类里面ProcessRequest方法这一句: var routeData = context.Request.RequestContext.RouteData; 。还记得上述注释3中封装的RequestContext对象吗,没错,这里就用到了这个对象,我们从这个对象里面取到当前请求的RouteData对象。
(7) ); 这一句不难理解:取到当前请求的的Controller名称。结果如下:
(8)得到控制器工厂这个没什么说的,为了简化,我们直接new了一个默认的控制器工厂。下面重点来看看 IController controller = factory.CreateController(context.Request.RequestContext, controllerName); 这一句。在控制器工厂的实现类里面实现了CreateController()这个方法。
public IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName) { if (requestContext == null) { ); } if (string.IsNullOrEmpty(controllerName)) { ); } //得到当前的控制类型 Type controllerType = GetControllerType(requestContext, controllerName); if (controllerType == null) { return null; } //得到控制器对象 IController controller = GetControllerInstance(requestContext, controllerType); return controller; } IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType) { var oRes = Activator.CreateInstance(controllerType) as IController; return oRes; } Type GetControllerType(System.Web.Routing.RequestContext requestContext, string controllerName) { routeNamespaces; object routeAssembly; requestContext.RouteData.Values.TryGetValue(, out routeNamespaces); requestContext.RouteData.Values.TryGetValue(, out routeAssembly); type = Assembly.Load(routeAssembly.ToString()).GetType(routeNamespaces.ToString() + + controllerName + ); return type; }