MVC 请求处理流程(一)

  路由系统先获取路由数据,在实现了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对象(这个是最忙的对象)!

[下一篇]

你可能感兴趣的:(mvc)