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

  我们发现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

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

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

时间: 2024-10-12 06:33:54

ASP.NET MVC 请求流程:Controller的相关文章

ASP.NET MVC 请求流程

一.应用程序启动 1.Application_Start方法,程序启动 2.RegisterRoutes方法,注册路由 3.System.Web.Mvc.RouteCollectionExtensions.MapRoute方法,出现了MvcRoutehandler对象 二.请求进入 在 “$\Windows\Microsoft.NET\Framework\版本号\Config\Web.config“ 中可以找到 " ” 证明请求会经过System.Web.Routing.UrlRoutingMo

.NET MVC请求流程

ASP.NET MVC 请求流程:Controller MvcHandler Action Action参数赋值

ASP.Net请求处理机制初步探索之旅 - Part 5 ASP.Net MVC请求处理流程

好听的歌 我一直觉得看一篇文章再听一首好听的歌,真是种享受.于是,我在这里嵌入一首好听的歌,当然你觉得不想听的话可以点击停止,歌曲 from 王菲 <梦中人>: 开篇:上一篇我们了解了在WebForm模式下一个Page页面的生命周期,它经历了初始化Init.加载Load以及呈现Render三个重要阶段,其中构造了页面控件树,并对页面控件树进行了大量的递归操作,最后将与模板结合生成的HTML返回给了浏览器.那么,在ASP.NET MVC模式下,一个页面的生命周期又经历了哪些步凑呢?别急,本篇漫漫

ASP.NET MVC的流程讲解

开始想这个标题的时候,很是忧郁到底叫什么标题会比较好哪,最后还是确定为讲解,虽然略显初级,但是很多概念,想通了还是比较有价值的.废话略过,开始! 1.MVC的基本开发流程   2.webform和MVC的选择   3.MVC的内部过程 1.MVC的开发流程 MVC的出现时微软在2009年左右开始提出的网站开发的新的发展方向,这个方面的开发官方解释是可以比较好的实现三层分离,而且分离之后,可以实现复用等相关好处,通常人们列举的例子是ui方面可以同时支持HTML网络或者WAP网络.但是其实个人的理解

白话ASP.NET MVC之三:Controller是如何解析出来的

我们在上一篇文章中介绍Controller激活系统中所涉及到的一些类型,比如有关Controller类型的相关定义类型就包括了IController类型,IAsyncController类型,ControllerBase抽象类型和我们最终要使用的抽象类型Controller,这是ASP.NET MVC 框架中和Controller本身定义相关的类型.其他辅助类型,包括管理Controller的类型ControllerFactory,这个工厂负责Controller的生产和销毁.我们还涉及到另一个

ASP.NET MVC深度接触:ASP.NET MVC请求生命周期

这篇博文的目的旨在详细描述ASP.NET MVC 请求从开始到结束的每一个过程.我希望能理解在浏览器输入URL 并敲击回车来请求一个ASP.NET MVC 网站的页面之后发生的任何事情. 为什么需要关心这些?有两个原因.首先是因为ASP.NET MVC 是一个扩展性非常强的框架.例如,我们可以插入不同的ViewEngine 来控制网站内容呈现的方式.我们还可以定义控制器生成和分配到某个请求的方式.因为我想发掘任何ASP.NET MVC 页面请求的扩展点,所以我要来探究请求过程中的一些步骤. 其次

ASP.NET MVC中 在controller 里将 Partial View 转化为字符串的方法

namespace Common.Helper { public static class ControllerExtension { //根据部分视图名称,把部分视图内容转换成字符串 public static string RenderPartialViewToString(this Controller controller, string partialViewName) { return controller.RenderPartialViewToString(partialViewN

从一个针对ASP.NET MVC框架的Controller.Action的请求处理顺序来说整个请求过程。

下面引用的所有代码都源自ASP.NET MVC的源码,但是只选取其中的一部分. System.Web.Routing.UrlRoutingModule在管道事件中注册PostResolveRequestCache事件. protected virtual void Init(HttpApplication application) { application.PostResolveRequestCache += OnApplicationPostResolveRequestCache; } 在这

【MVC】ASP.NET MVC 请求生命周期

当一个asp.net mvc应用程序提出请求,为了响应请求,包含一些请求执行流程步骤! 在asp.net mvc应用程序Http request和Http response 过程中,主要包含8个步骤: 1)RouteTable(路由表)的创建      2)UrlRoutingModule 请求拦截      3)Routing engine 确定route      4)route handler 创建相关的IHttpHandler实例      5)IHttpHandler实例确定Contr