1.請求進入時,.NET Framework就找出全部的HttpModule,以此調用它們的Init方法,以下圖所示,咱們重點關注"UrlRoutingModule-4.0"的HttpModule.app
2.咱們看看UrlRoutingModule方法中作了哪些操做異步
.async
繼續往下看ide
咱們來到了PostResolveRequestCache方法中,咱們進入RouteCollection.GetRouteData()方法中看下,以下所示ui
看過上節的同窗會知道這裏的routeData就是System.Web.Mvc.RouteData實例,routeHandler就是System.Web.Mvc.MvcRouteHandler實例,咱們來看下它們所包含的值,以下圖所示。spa
此次咱們進入routeHandler.GetHttpHandler()方法中看看,以下圖所示code
在上圖中,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中的內部結構看下,以下:blog
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
就到這吧,後面就是經過反射了。
好了,就、這就是請求進入到控制器操做的基本流程了。