1.請求進入時,.NET Framework就找出所有的HttpModule,以此調用它們的Init方法,如下圖所示,我們重點關注"UrlRoutingModule-4.0"的HttpModule.
2.我們看看UrlRoutingModule方法中做了哪些操作
.
繼續往下看
我們來到了PostResolveRequestCache方法中,我們進入RouteCollection.GetRouteData()方法中看下,如下所示
看過上節的同學會知道這里的routeData就是System.Web.Mvc.RouteData實例,routeHandler就是System.Web.Mvc.MvcRouteHandler實例,我們來看下它們所包含的值,如下圖所示。
這次我們進入routeHandler.GetHttpHandler()方法中看看,如下圖所示
在上圖中,GetHttpHandler方法內主要做了兩步,第一步就是通過獲取當前MVC的會話狀態來設置此次請求的會話狀態模式,第二步就是返回一個MvcHandler實例,通過返回類型我們不難推出MvcHandler是實現了IHttpHandler接口的,據我們所知實現了IHttpHandle接口的類所謂被調用內部的ProcessRequest方法,所以下一步的目標就是System.Web.Mvc.MvcHandler.ProcessRequest方法了。在這里需要注意了,傳入參數requestContext現在包含了兩個實例,一個是HttpContext,另一個就是包含了我們在程序中定義的路由信息的對象——RouteData。
好了,我們繼續進行,來看看System.Web.Mvc.MvcHandler.ProcessRequest()方法,但是突然發現System.Web.Mvc.MvcHandler.ProcessRequest方法壓根就沒有被調用,這是什么一回事?我們先把System.Web.Mvc.MvcHandler中的內部結構看下,如下:

public class MvcHandler : IHttpAsyncHandler, IHttpHandler, IRequiresSessionState { // 省略很多代碼 public MvcHandler(RequestContext requestContext); protected virtual IAsyncResult BeginProcessRequest(); protected virtual void EndProcessRequest(); private static string GetMvcVersionString(); protected virtual void ProcessRequest(HttpContext httpContext); private void ProcessRequestInit(HttpContextBase httpContext, out IController controller, out IControllerFactory factory); }
我們發現MvcHandler不止實現的IHttpHandler即接口,還實現了異步的IHttpAsyncHandler接口,那么如果程序不調用同步的ProcessRequest方法,那就一定是使用的異步的BeginProcessRequest方法。
這是正確的,MVC5使用的異步的BeginProcessRequest方法,接下來我們去BeginProcessRequest方法中看看有哪些秘密吧。

protected virtual IAsyncResult BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, object state) { HttpContextBase httpContextBase = new HttpContextWrapper(httpContext); return BeginProcessRequest(httpContextBase, callback, state); }
向下找
protected internal virtual IAsyncResult BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, object state) { IController controller; IControllerFactory factory;
//創建控制器 ProcessRequestInit(httpContext, out controller, out factory); IAsyncController asyncController = controller as IAsyncController; if (asyncController != null) { // asynchronous controller // Ensure delegates continue to use the C# Compiler static delegate caching optimization. BeginInvokeDelegate<ProcessRequestState> beginDelegate = delegate(AsyncCallback asyncCallback, object asyncState, ProcessRequestState innerState) { try {
// Action return innerState.AsyncController.BeginExecute(innerState.RequestContext, asyncCallback, asyncState); } catch {
// 釋放控制器 innerState.ReleaseController(); throw; } }; EndInvokeVoidDelegate<ProcessRequestState> endDelegate = delegate(IAsyncResult asyncResult, ProcessRequestState innerState) { try { innerState.AsyncController.EndExecute(asyncResult); } finally { innerState.ReleaseController(); } }; ProcessRequestState outerState = new ProcessRequestState() { AsyncController = asyncController, Factory = factory, RequestContext = RequestContext }; SynchronizationContext callbackSyncContext = SynchronizationContextUtil.GetSynchronizationContext(); return AsyncResultWrapper.Begin(callback, state, beginDelegate, endDelegate, outerState, _processRequestTag, callbackSyncContext: callbackSyncContext); } else { // synchronous controller Action action = delegate { try { controller.Execute(RequestContext); } finally { factory.ReleaseController(controller); } }; return AsyncResultWrapper.BeginSynchronous(callback, state, action, _processRequestTag); } }
我們先進入System.Web.Mvc.MvcHandler.ProcessRequestInit方法內看看,如下圖所示
再深入一點,看看factory.CreateController方法
再看看GetControllerType
就到這吧,后面就是通過反射了。
好了,就、這就是請求進入到控制器操作的基本流程了。