在知道asp.net mvc 流程之前,必须知道完整的http请求在asp.net framework中的处理流程:

HttpRequest-->inetinfo.exe->ASPNET_ISAPI.DLL-->Http Pipeline-->ASPNET_WP.EXE-->HttpRuntime-->HttpApplication Factory-->HttpApplication-->HttpModule-->HttpHandler Factory-->HttpHandler-->HttpHandler.ProcessRequest()

具体参考过程

从底层了解ASP.NET体系结构


下面简要描述下 asp.net mvc 处理流程:

1、在Web. config中 注册
  1. <modules>
  2.    
  3.       <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=0.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
  4.     </modules>
复制代码
2、在Global中设置 System.Web.Routing.RouteTable.Routes 的值,应用于解析Url,得到相应的Controller,Action,和RouteData
  1. public static void RegisterRoutes(RouteCollection routes)
  2.         {
  3.             routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

  4.             routes.MapRoute(
  5.                 "Default",                                              // Route name
  6.                 "{controller}/{action}/{id}",                          // URL with parameters
  7.                 new { controller = "Contact", action = "Index", id = "" }  // Parameter defaults
  8.             );

  9.         }

  10.         protected void Application_Start()
  11.         {
  12.             RegisterRoutes(RouteTable.Routes);
  13.         }
复制代码
在MVC对RouteCollection 的扩展方法中,有MapRoute
  1. public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces) {
  2.             if (routes == null) {
  3.                 throw new ArgumentNullException("routes");
  4.             }
  5.             if (url == null) {
  6.                 throw new ArgumentNullException("url");
  7.             }

  8.             Route route = new Route(url, new MvcRouteHandler()) {
  9.                 Defaults = new RouteValueDictionary(defaults),
  10.                 Constraints = new RouteValueDictionary(constraints)
  11.             };

  12.             if ((namespaces != null) && (namespaces.Length > 0)) {
  13.                 route.DataTokens = new RouteValueDictionary();
  14.                 route.DataTokens["Namespaces"] = namespaces;
  15.             }

  16.             routes.Add(name, route);

  17.             return route;
  18.         }
复制代码
3、发送Http请求,因为在第1部注册了System.Web.Routing.UrlRoutingModule ,在执行到 HttpModule 时就调用IHttpModule接口的 Init 方法
  1. protected virtual void Init(HttpApplication application)
  2. {
  3.     application.PostResolveRequestCache += new EventHandler(this.OnApplicationPostResolveRequestCache);
  4.     application.PostMapRequestHandler += new EventHandler(this.OnApplicationPostMapRequestHandler);
  5. }
复制代码
1)我们看 Init 中的调用 application.PostResolveRequestCache += new EventHandler(this.OnApplicationPostResolveRequestCache);下的代码
  1. private void OnApplicationPostResolveRequestCache(object sender, EventArgs e)
  2. {
  3.     HttpContextBase context = new HttpContextWrapper(((HttpApplication) sender).Context);
  4.     this.PostResolveRequestCache(context);
  5. }
复制代码
再看this.PostResolveRequestCache(context);的调用
  1. public virtual void PostResolveRequestCache(HttpContextBase context)
  2. {
  3.     RouteData routeData = this.RouteCollection.GetRouteData(context);
  4.     if (routeData != null)
  5.     {
  6.         IRouteHandler routeHandler = routeData.RouteHandler;
  7.         if (routeHandler == null)
  8.         {
  9.             throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, RoutingResources.UrlRoutingModule_NoRouteHandler, new object[0]));
  10.         }
  11.         if (!(routeHandler is StopRoutingHandler))
  12.         {
  13.             RequestContext requestContext = new RequestContext(context, routeData);
  14.             IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext);
  15.             if (httpHandler == null)
  16.             {
  17.                 throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, RoutingResources.UrlRoutingModule_NoHttpHandler, new object[] { routeHandler.GetType() }));
  18.             }
  19.             context.Items[_requestDataKey] = new RequestData { OriginalPath = context.Request.Path, HttpHandler = httpHandler };
  20.             context.RewritePath("~/UrlRouting.axd");
  21.         }
  22.     }
  23. }
复制代码
我们发现 IRouteHandler routeHandler = routeData.RouteHandler;  行把routeHandler赋了具体值。但 routeData.RouteHandler如何来的? 在第2部MapRoute的调用中,我们得到了它。通过routeHandler,我们得到了 IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext);然后,通过context.Items[_requestDataKey] = new RequestData { OriginalPath = context.Request.Path, HttpHandler = httpHandler };我们把httpHandler 存入context.Items字段中。

2) 我们看 Init 中的调用 application.PostMapRequestHandler += new EventHandler(this.OnApplicationPostMapRequestHandler); 下的代码
  1. private void OnApplicationPostMapRequestHandler(object sender, EventArgs e)
  2. {
  3.     HttpContextBase context = new HttpContextWrapper(((HttpApplication) sender).Context);
  4.     this.PostMapRequestHandler(context);
  5. }
复制代码
  1. public virtual void PostMapRequestHandler(HttpContextBase context)
  2. {
  3.     RequestData data = (RequestData) context.Items[_requestDataKey];
  4.     if (data != null)
  5.     {
  6.         context.RewritePath(data.OriginalPath);
  7.         context.Handler = data.HttpHandler;
  8.     }
  9. }
复制代码
我们通过 RequestData data = (RequestData) context.Items[_requestDataKey];得到了存入 RequestData的RequestData 对象,再通过 context.Handler = data.HttpHandler;设置处理Http请求的IhttpHandler对象,也就是MvcRouteHandler对象。

可以看出:1)我们得到了 MvcRouteHandler对象。2)我们把MvcRouteHandler对象赋给了context.Handler
TOP