码迷,mamicode.com
首页 > Web开发 > 详细

MVC 请求处理流程(一)

时间:2015-03-13 10:37:29      阅读:508      评论:0      收藏:0      [点我收藏+]

标签:

  路由系统先获取路由数据,在实现了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 请求处理流程(一)

标签:

原文地址:http://www.cnblogs.com/lpandnn/p/2888480.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!