ASP.NET MVC 请求流程:Controller

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);
        }
View Code

  咱们发现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);
    }
View Code

  向下找

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

  就到这吧,后面就是经过反射了。

  好了,就、这就是请求进入到控制器操做的基本流程了。

相关文章
相关标签/搜索