路由系统先获取路由数据,在实现了IHttpModule接口的UrlRoutingModule对象中通过注册HttpApplication的PostResolveRequestCache来解析路由数据并对请求进行映射;
protected virtual void Init(HttpApplication application) { if (application.Context.Items[UrlRoutingModule._contextKey] != null) return; application.Context.Items[UrlRoutingModule._contextKey] = UrlRoutingModule._contextKey; application.PostResolveRequestCache += new EventHandler(this.OnApplicationPostResolveRequestCache); } public virtual void PostResolveRequestCache(HttpContextBase context) { RouteData routeData = this.RouteCollection.GetRouteData(context); if (routeData == null) return; IRouteHandler routeHandler = routeData.RouteHandler; if (routeHandler == null) throw new InvalidOperationException(string.Format((IFormatProvider) CultureInfo.CurrentCulture, System.Web.SR.GetString("UrlRoutingModule_NoRouteHandler"), new object[0])); if (routeHandler is StopRoutingHandler) return; RequestContext requestContext = new RequestContext(context, routeData); context.Request.RequestContext = requestContext; IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext);//获取的为MvcHandler if (httpHandler == null) throw new InvalidOperationException(string.Format((IFormatProvider) CultureInfo.CurrentUICulture, System.Web.SR.GetString("UrlRoutingModule_NoHttpHandler"), new object[1] { (object) routeHandler.GetType() })); else if (httpHandler is UrlAuthFailureHandler) { if (!FormsAuthenticationModule.FormsAuthRequired) throw new HttpException(401, System.Web.SR.GetString("Assess_Denied_Description3")); UrlAuthorizationModule.ReportUrlAuthorizationFailure(HttpContext.Current, (object) this); } else context.RemapHandler(httpHandler); }
路由数据有个 IRouteHandler RouteHandler属性,注册路由时这个属性默认为MvcRouteHandler
public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces) { if (routes == null) throw new ArgumentNullException("routes"); if (url == null) throw new ArgumentNullException("url"); Route route = new Route(url, (IRouteHandler) new MvcRouteHandler()) { Defaults = RouteCollectionExtensions.CreateRouteValueDictionary(defaults), Constraints = RouteCollectionExtensions.CreateRouteValueDictionary(constraints), DataTokens = new RouteValueDictionary() }; if (namespaces != null && namespaces.Length > 0) route.DataTokens["Namespaces"] = (object) namespaces; routes.Add(name, (RouteBase) route); return route; }
RouteHandler有个GetHttpHandler方法来获取对当前请求进行映射的HttpHandler(会话状态也是在这个阶段设置的,通过controllerFactory.GetControllerSessionBehavior()方法)
public MvcRouteHandler(IControllerFactory controllerFactory) { this._controllerFactory = controllerFactory; } protected virtual SessionStateBehavior GetSessionStateBehavior(RequestContext requestContext) { string controllerName = (string) requestContext.RouteData.Values["controller"]; if (string.IsNullOrWhiteSpace(controllerName)) throw new InvalidOperationException(MvcResources.MvcRouteHandler_RouteValuesHasNoController); else return (this._controllerFactory ?? ControllerBuilder.Current.GetControllerFactory()).GetControllerSessionBehavior(requestContext, controllerName); } protected virtual IHttpHandler GetHttpHandler(RequestContext requestContext) { requestContext.HttpContext.SetSessionStateBehavior(this.GetSessionStateBehavior(requestContext)); return (IHttpHandler) new MvcHandler(requestContext); }
返回的是一个实现了IHttpHandler的MvcHandler对象, 在MvcHandler的请求处理方法ProcessRequest中调用了ProcessRequestInit方法,代码如下:
protected internal virtual void ProcessRequest(HttpContextBase httpContext) { IController controller; IControllerFactory factory; this.ProcessRequestInit(httpContext, out controller, out factory);//获取到当前的controller对象 try { controller.Execute(this.RequestContext);//进行进一步的方法调用 } finally { factory.ReleaseController(controller);//完成后释放 } } private void ProcessRequestInit(HttpContextBase httpContext, out IController controller, out IControllerFactory factory) { HttpContext current = HttpContext.Current; if (current != null) { bool? nullable = ValidationUtility.IsValidationEnabled(current); if ((!nullable.GetValueOrDefault() ? 0 : (nullable.HasValue ? 1 : 0)) != 0) ValidationUtility.EnableDynamicValidation(current); } this.AddVersionHeader(httpContext); this.RemoveOptionalRoutingParameters(); string requiredString = this.RequestContext.RouteData.GetRequiredString("controller"); factory = this.ControllerBuilder.GetControllerFactory(); controller = factory.CreateController(this.RequestContext, requiredString); if (controller != null) return; throw new InvalidOperationException(string.Format((IFormatProvider) CultureInfo.CurrentCulture, MvcResources.ControllerBuilder_FactoryReturnedNull, new object[2] { (object) factory.GetType(), (object) requiredString })); }
以上方法中通过工厂ControllerFactoryController创建Controller的方法详见:[controller的创建"]。controller的Execute方法是在其基类ControllerBase中 实现的
protected virtual void Execute(RequestContext requestContext) { if (requestContext == null) throw new ArgumentNullException("requestContext"); if (requestContext.HttpContext == null) throw new ArgumentException(MvcResources.ControllerBase_CannotExecuteWithNullHttpContext, "requestContext"); this.VerifyExecuteCalledOnce(); this.Initialize(requestContext); using (ScopeStorage.CreateTransientScope()) this.ExecuteCore(); }
在其子类controller中重写了方法ExecuteCore
protected override void ExecuteCore() { this.PossiblyLoadTempData(); try { //获取动作方法名称 string requiredString = this.RouteData.GetRequiredString("action"); if (this.ActionInvoker.InvokeAction(this.ControllerContext, requiredString)) return; this.HandleUnknownAction(requiredString); } finally { this.PossiblySaveTempData(); } }
在这里使用到了ActionInvoker属性,它对应的是实现了IActionInvoker接口的一个对象!默认为获取在this.CreateActionInvoker()方法中,为AsyncControllerActionInvoker对象(这个是最忙的对象)!