• 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对象(这个是最忙的对象)!

    [下一篇]

  • 相关阅读:
    js 中 && 和 ||
    The server time zone value 'EDT' is unrecognized or represents more than one time zone.
    docker进入容器
    docker 挂载本地目录
    Docker for Windows 挂载目录失败
    docker下redis启动 根据本地配置文件
    docker 安装 nacos/nacos-server 镜像并配置本地数据库
    spring cloud Nacos Config配置中心
    Docker卸载
    虚拟机centos添加硬盘和分区挂载
  • 原文地址:https://www.cnblogs.com/lpandnn/p/2888480.html
Copyright © 2020-2023  润新知