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
就到这吧,后面就是通过反射了。
好了,就、这就是请求进入到控制器操作的基本流程了。
ASP.NET MVC 请求流程:Controller的更多相关文章
- asp.net mvc请求流程
收对应用程序的第一个请求 > 执行路由 > 创建 MVC 请求处理程序 > 创建控制器 > 执行控制器 > 调用操作 > 执行结果
- ASP.NET MVC 请求流程:Route
1.RouteTable RouteTable翻译过来的意思就是路由表,一个Web应用程序具有一个全局的路由表,该路由表通过System.Web.Routiing.RouteTable的静态只读属性R ...
- ASP.NET MVC 请求流程
一.应用程序启动 1.Application_Start方法,程序启动 2.RegisterRoutes方法,注册路由 3.System.Web.Mvc.RouteCollectionExtensio ...
- .NET MVC请求流程
ASP.NET MVC 请求流程:Controller MvcHandler Action Action参数赋值 .NET MVC权限设计思考之切入点
- ASP.Net请求处理机制初步探索之旅 - Part 5 ASP.Net MVC请求处理流程
好听的歌 我一直觉得看一篇文章再听一首好听的歌,真是种享受.于是,我在这里嵌入一首好听的歌,当然你觉得不想听的话可以点击停止,歌曲 from 王菲 <梦中人>: --> 开篇:上一篇 ...
- ASP.Net MVC请求处理流程
ASP.Net MVC请求处理流程 好听的歌 我一直觉得看一篇文章再听一首好听的歌,真是种享受.于是,我在这里嵌入一首好听的歌,当然你觉得不想听的话可以点击停止,歌曲 from 王菲 <梦中人& ...
- 白话ASP.NET MVC之三:Controller是如何解析出来的
我们在上一篇文章中介绍Controller激活系统中所涉及到的一些类型,比如有关Controller类型的相关定义类型就包括了IController类型,IAsyncController类型,Cont ...
- ASP.NET MVC 3.0 Controller基础
ASP.NET MVC 3.0 Controller基础 1.Controller类与方法 Controller(控制器)是ASP.NET MVC的核心,负责处理浏览器请求,并作出响应.Cotro ...
- asp.net mvc 请求处理流程,记录一下。
asp.net mvc 请求处理流程,记录一下.
随机推荐
- 难道只有我一个人想吐槽npm这种包管理方式么
实在忍不住吐槽 说实话有强迫症的我忍了很久了,实在是忍不住写篇文章来吐槽一下. 标题可能说的有点大了,我要吐槽的是:我可能只需要某一个小小的功能模块A,结果模块A依赖B-F这5个模块,然后B又依赖这1 ...
- 用C#Winform写个简单的批量清空文件内容和删除文件的小工具
用C#Winform写个简单的批量清空文件内容和删除文件的小工具 本文介绍这个简单得不能再简单的小项目.做这个项目,有以下目的. 1 当然是做个能用的工具 2 学习使用Github 关于用VS2013 ...
- Linux gcc的安装
说明:我是在虚拟机里学习的Linux,很多问题也是和虚拟机有关的.今天就遇到了虚拟机安装gcc是一个问题. 首先查看gcc是否安装: 然后安装gcc.(我的错误就出现在这里.) 我用的虚拟机,练习平时 ...
- 数据库的Timeout
数据库的Timeout 其实有很多种情况. 一个是执行的超时时间 executionTimeOut,一个是连接的超时时间connectionTimeOut, 还有呢? 等待的超时时间 ReadTime ...
- inoic start projectname sidemenu报错 - Error: Cannot find module 'lodash._baseslice'
inoic start projectname sidemenu报错 - Error: Cannot find module 'lodash._baseslice' 在公司的电脑上出现过这个错误,后来 ...
- tool list
http://www.pairwise.org/tools.asp 用例设计工具 组合测试工具pict 代码调试 Findbugs 介绍及使用方法 接口测试工具 webservices studi ...
- urldecode解码方法
输入为带有urldecode转码文本,输出正常文本. //20130625 by zhangyl private string ConvertToString(string input) { inpu ...
- android TextView 文字垂直的设置
<TextView android:id="@+id/tv_status" android:layout_width="wrap_content" and ...
- SQL PASS将于8月24日在北京中医药大学举办线下活动
活动主题:复制架构的实现和调优以及SQL Server BI在传统行业的应用 地点:北三环东路11号 北京中医药大学 白色的1号楼教学楼后楼5层511房间 时间:2013年8月24日 9:00-12: ...
- DOM一致性检测
[implementation] 由于DOM分为多个级别,也包含多个部分,因此检测浏览器实现了DOM的哪些部分就十分必要.document.implementation属性就是这些提供相应信息和功能的 ...