zoukankan      html  css  js  c++  java
  • ASP.NET MVC 请求流程:Controller

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

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

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

  • 相关阅读:
    Win10/UWP开发-Ink墨迹书写
    Win10/UWP 让你的App使用上扫描仪
    Win10/UWP新特性—Drag&Drop 拖出元素到其他App
    UWP/Win10新特性系列—Drag&Drop 拖动打开文件
    1、WIN2D学习记录(win2d实现JS雨天效果)
    Windows 通用应用尝试开发 “51单片机汇编”总结
    D2.Reactjs 操作事件、状态改变、路由
    D1.1.利用npm(webpack)构建基本reactJS项目
    UWP 动画系列之模仿网易云音乐动画
    字符设备驱动之Led驱动学习记录
  • 原文地址:https://www.cnblogs.com/zxj159/p/4115271.html
Copyright © 2011-2022 走看看