mvc请求管道(一)
一、前言
在平常做后台开发的时候,经常会说到请求管道,很多开发者都知道这个,也能说几句,可能没法详细的去介绍,今天就来详细的说一下这个。
二、到达IIS之前
请看下面这个流程图。从用户打开浏览器到请求到达服务器,这些都是需要我们去配置就行了,这里面有一些知识点,http/https、tcp/ip、dns解析这些感兴趣的可以去了解一下。
三、请求到达IIS
同样先看流程图,Sys服务监听到有请求到达IIS,IIS会把这个请求转发给ISAPI,ISAPI即Internet Server Application Program Interface (互联网应用服务接口),是微软提供的一套面向Internet服务的API接口,它根据后缀判断需要把该请求转发给谁处理,.net的请求会转发到asp.net_ISAPI,它属于IIS,运行在IIS进程中的,它会用Pipeline的方式把请求转交给.Net Framework,它很像一个队列(先进先出),可以对请求进行排队处理,在请求处理完,会释放掉该请求占用的socket链接。
四、请求到达应用程序
惯例,先上图。HTTPRuntime.ProcessRequest是整个应用程序的入口,这一步会接收上一步打包的HTTPWorkerRequest,完成HttpContext的初始化,调用HttpApplicaFactory工厂类创建HttpApplication(HttpApplication实现了IHttpHandler),HttpApplicationFactory.GetApplicationInstance创建HttpApplication实例中有三个关键方法:
1. HttpApplicationFactory._theApplicationFactory.EnsureInited()该方法检查HttpApplicationFactory是否被初始化(它是存放在一个栈里面的)如果没有,就通过HttpApplicationFactory.Init()进行初始化。在Init()中,先获取Global.asax文件的完整路径,然后调用CompileApplication()对Global.asax进行编译。
2. HttpApplicationFactory._theApplicationFactory.EnsureAppStartCalled(context) 创建特定的HttpApplication实例,触发ApplicationOnStart事件,执行ASP.Global.asax中的Application_Start(object sender, EventArgs e)方法。这里创建的HttpApplication实例在处理完事件后,就被回收。
3. HttpApplicationFactory._theApplicationFactory.GetNormalApplicationInstance(context) 该方法创建HttpApplication实例并进行初始化,调用System.Web.HttpApplication.InitInternal()方法。创建HttpApplication实例是根据实际的_theApplicationType进行创建。如果Web目录中没有global.asa文件,也就是说没有动态编译生成ASP.Global.asax类型,那就直接实例化HttpApplication。如果创建了ASP.Global.asax类型,那就对ASP.Global.asax进行实例化。
五、请求到达MVC的处理管线
上面大概介绍了Asp.Net Mvc的请求到达应用程序的管道,接下来就是和我们编码息息相关的处理流程了,下面这张图是我在以前查阅资料的时候保存下来了,出处已经找不到,如果有知道可以留个言。
当请求到达应用程序之后,第一站就是路由模块,MVC会根据RouteTable(一般都在RouteConfig中配置,在MVC第一次启动时,路由系统就会把我们注册的路由规则,写在Glocal.asax中的Application_Start事件中)中配置的路由模板去匹配当前的请求,获取对应的Controller和Action信息,具体的匹配过程是由UrlRoutingModule(System.Web.Routing.UrlRoutingModule)来实现的。
当UrlRoutingModule在Route Table中找到一条匹配的路由规则时,就会为这条路由规则寻找对应的IRouteHandler(System.Web.Mvc.IRouteHandler)实例(默认是System.Web.MvcRouteHandler),根据这个RouteHandler最后获取一个IHttpHandler的实例(默认是System.Web.MvcHandler)。在处理完路由信息和匹配到之后,就来到了Controller。
在MvcHandler中的ProcessRequest方法中就是ASP.NET MVC的生命周期,这个方法使用IControllerFactory的实例(默认是System.Web.Mvc.DefaultControllerFactory)来创建相应的Controller。
创建完Controller之后,就会执行Controller的invokeAction()方法,找到合适的Action后,就是Model Binding(默认是System.Web.Mvc.DefaultModelBinder),它会从Http请求的参数中提取数据并实现类型转换,数据校验(例如是否必填,数据格式等)以及是否自动装配到Action方法的参数中。
完成模型绑定之后就是执行Filter了,Filter也是一个可以铺开说的知识,这里先只简单的介绍一下,从下图看到第一个是Authentication Filter,它是MVC5中新增的一个Filter,它会先于Authorization Filter执行,目的是对访问用户的认证。在MVC5之前,认证和授权都是通过Authorization Filter来实现的。然后是Authorization Filter 这个主要是验证授权的,授权验证通过后执行的Action Filter,自定义Action Filter需继承ActionFilterAttribute,它分为两个方法,OnActionExecuting和OnActionExecuted分别在action执行前后执行,我们可以通过实现IActionFilter接口来实现你个性化的过滤机制。在Action Filter执行之后,就会执行我们的业务代码了。
在执行完业务代码,会执行ActionResult,ActionResult也有一个Filter,自定义ActionResult Filter需继承ActionFilterAttribute它也分为两个方法:OnResultExecuting和OnResultExecuted,它是在动作结果被执行之前和之后运行。ActionResult就是把后台处理的用户请求结果返回。因此ViewResult、PartialViewResult、RedirectToRouteResult、RedirectResult、ContentResult、JsonResult、FileResult 和 EmptyResult就是具体的返回类型。
最后还有一个Exception Filter,它只有在当Action执行发生未处理异常的时候执行OnException方法。自定义Exception Filter需要继承HandleErrorAttribute类,重写OnException方法。
在ActionResult执行完成之后,就是View的初始化和渲染了,ViewResult最终是由View Engine通过调用IView的Render()方法来呈现View的,整个处理过程是由IViewEngine(System.Web.Mvc.IViewEngine)来实现的。ASP.Net MVC 默认提供WebForm(.aspx)和Razor(.cshtml)模板引擎,你也可以通过实现IViewEngine接口来实现你自己的ViewEngine,然后在Application_Start方法中做如下操作:
protected void Application_Start()
{
//移除所有的View引擎包括Webform和Razor
ViewEngines.Engines.Clear();
//注册你自己的View引擎
ViewEngines.Engines.Add(new CustomViewEngine());
}
在页面里,我们可以直接写html标签,也可以用@Html等来实现。@Html是使用Html Helpers来生成我们需要的html标签,当然它也支持自定义和扩展,这样就可以解决我们一些定制化的需求。
六、总结
在上面所有的操作都完成之后,IIS会把结果返回给用户,用户才能看到他需要的结果。在整个请求管道中,一般分为19个事件,如下,
事件名称: |
简单描述: |
BeginRequest |
在 ASP.NET 响应请求时作为 HTTP 执行管线链中的第一个事件发生 |
AuthenticateRequest |
当安全模块已建立用户标识时发生。注:AuthenticateRequest 事件发出信号表示配置的身份验证机制已对当前请求进行了身份验证。预订 AuthenticateRequest 事件可确保在处理附加的模块或事件处理程序之前对请求进行身份验证 |
PostAuthenticateRequest |
当安全模块已建立用户标识时发生。PostAuthenticateRequest 事件在 AuthenticateRequest 事件发生之后引发。预订 PostAuthenticateRequest 事件的功能可以访问由 PostAuthenticateRequest 处理的任何数据 |
AuthorizeRequest |
当安全模块已验证用户授权时发生。AuthorizeRequest 事件发出信号表示 ASP.NET 已对当前请求进行了授权。预订 AuthorizeRequest 事件可确保在处理附加的模块或事件处理程序之前对请求进行身份验证和授权 |
PostAuthorizeRequest |
在当前请求的用户已获授权时发生。PostAuthorizeRequest 事件发出信号表示 ASP.NET 已对当前请求进行了授权。预订PostAuthorizeRequest 事件可确保在处理附加的模块或处理程序之前对请求进行身份验证和授权 |
ResolveRequestCache |
当 ASP.NET 完成授权事件以使缓存模块从缓存中为请求提供服务时发生,从而跳过事件处理程序(例如某个页或 XML Web services)的执行 |
PostResolveRequestCache |
在 ASP.NET 跳过当前事件处理程序的执行并允许缓存模块满足来自缓存的请求时发生。)在 PostResolveRequestCache 事件之后、PostMapRequestHandler 事件之前创建一个事件处理程序(对应于请求 URL 的页 |
PostMapRequestHandler |
在 ASP.NET 已将当前请求映射到相应的事件处理程序时发生。 |
AcquireRequestState |
当 ASP.NET 获取与当前请求关联的当前状态(如会话状态)时发生。 |
PostAcquireRequestState |
在已获得与当前请求关联的请求状态(例如会话状态)时发生。 |
PreRequestHandlerExecute |
恰好在 ASP.NET 开始执行事件处理程序(例如,某页或某个 XML Web services)前发生。 |
PostRequestHandlerExecute |
在 ASP.NET 事件处理程序(例如,某页或某个 XML Web service)执行完毕时发生。 |
ReleaseRequestState |
在 ASP.NET 执行完所有请求事件处理程序后发生。该事件将使状态模块保存当前状态数据。 |
PostReleaseRequestState |
在 ASP.NET 已完成所有请求事件处理程序的执行并且请求状态数据已存储时发生。 |
UpdateRequestCache |
当 ASP.NET 执行完事件处理程序以使缓存模块存储将用于从缓存为后续请求提供服务的响应时发生。 |
PostUpdateRequestCache |
在 ASP.NET 完成缓存模块的更新并存储了用于从缓存中为后续请求提供服务的响应后,发生此事件。 |
LogRequest |
在 ASP.NET 完成缓存模块的更新并存储了用于从缓存中为后续请求提供服务的响应后,发生此事件。 仅在 IIS 7.0 处于集成模式并且 .NET Framework 至少为 3.0 版本的情况下才支持此事件 |
PostLogRequest |
在 ASP.NET 处理完 LogRequest 事件的所有事件处理程序后发生。 仅在 IIS 7.0 处于集成模式并且 .NET Framework 至少为 3.0 版本的情况下才支持此事件。 |
EndRequest |
在 ASP.NET 响应请求时作为 HTTP 执行管线链中的最后一个事件发生。 在调用 CompleteRequest 方法时始终引发 EndRequest 事件。 |
写的可能不是十分详细,基本也差不多了,如果有什么不对的地方欢迎指正。
mvc请求管道(一)的更多相关文章
- 13、ASP.NET MVC入门到精通——MVC请求管道
本系列目录:ASP.NET MVC4入门到精通系列目录汇总 ASP.NET MVC的请求管道和ASP.NET请求管道基本上一模一样,如果你对ASP.NET请求管道十分熟悉的话,你只要关注一下不同点.看 ...
- ASP.NET MVC入门到精通——MVC请求管道
https://www.cnblogs.com/jiekzou/p/4896315.html 本系列目录:ASP.NET MVC4入门到精通系列目录汇总 ASP.NET MVC的请求管道和ASP.NE ...
- MVC请求管道
下面是请求管道中的19个事件. (1)BeginRequest: 开始处理请求 (2)AuthenticateRequest授权验证请求,获取用户授权信息 (3):PostAuthenticateRe ...
- Asp.net MVC进入请求管道的过程
Asp.net MVC进入请求管道的过程 Asp.Net MVC 跟AspNet 入口解释 Asp.Net MVC请求处理过程 mvc 请求模型 mvc的原理 mvc模型 NewMVCPipleLin ...
- ASP.NET MVC请求处理管道生命周期的19个关键环节(1-6)
ASP.NET和ASP.NET MVC的HttpApplication请求处理管道有共同的部分和不同之处,本系列将体验ASP.NET MVC请求处理管道生命周期的19个关键环节. ①以IIS6.0为例 ...
- 【深入ASP.NET原理系列】--ASP.NET请求管道、应用程序生命周期、整体运行机制
微软的程序设计和相应的IDE做的很棒,让人很快就能有生产力..NET上手容易,生产力很高,但对于一个不是那么勤奋的人,他很可能就不再进步了,没有想深入下去的动力,他不用去理解整个框架和环境是怎么执行的 ...
- ASP.NET MVC请求处理管道生命周期的19个关键环节(7-12)
在上一篇"ASP.NET MVC请求处理管道生命周期的19个关键环节(1-6) ",体验了1-6关键环节,本篇继续. ⑦根据IsapiWorkerRequest对象,HttpRun ...
- ASP.NET MVC请求处理管道生命周期的19个关键环节(13-19)
在上一篇"ASP.NET MVC请求处理管道生命周期的19个关键环节(7-12) ",体验了7-12关键环节,本篇继续. ⒀当请求到达UrlRoutingModule的时候,Url ...
- MVC请求过程 简单分析(一)
在服务端判断客户端传过来的文件的类型,如果是静态文件,直接返回,在页面输出显示.如果是动态文件,通过aspnet_isapi.dll转交过.NetFrameWork框架执行. 创建ISAPIrunti ...
随机推荐
- [币严BIZZAN区块链]数字货币交易所钱包对接之比特币(BTC)
在币严BIZZAN开发数字货币交易所的过程中,一共有两大难点,一个是高速撮合交易引擎,另一个是钱包对接,这两者是我们团队以前没有接触过的.这个系列的文章主要介绍数字货币交易所钱包对接实现技术.第一个要 ...
- SpringBoot 2 快速整合 | Hibernate Validator 数据校验
概述 在开发RESTFull API 和普通的表单提交都需要对用户提交的数据进行校验,例如:用户姓名不能为空,年龄必须大于0 等等.这里我们主要说的是后台的校验,在 SpringBoot 中我们可以通 ...
- ThreadLocal的认知与见解
ThreadLocal:提高一个线程的局部变量,访问某个线程拥有自己局部变量(很难理解.看看下面这句话,顺便再讲个例子). 当使用ThreadLocal维护变量时,ThreadLocal为每一个使用该 ...
- javaweb应用程序概述
1.HTTP(超文本传输协议),它是一种主流的B/S架构中应用的通信协议.具有以下特点: 1.1.无状态:服务不会记录客户端每次提交的请求,服务器一旦响应客户端之后,就会结束本次的通信过程,客户端下一 ...
- px、em、rem、%、vw、vh、vm这些单位的区别
1.px px就是像素,也是我们现在经常使用的基本单位,比如常常听到的电脑像素是1024x768的,表示的是水平方向是1024个像素点,垂直方向是768个像素点. 2.em em参考物是父元素的fon ...
- spring aop介绍和示例
参考:<Spring in Action> 一.AOP介绍 AOP是Aspect Oriented Programming的缩写,意思是面向切面编程. 应用中有一些功能使用非常普遍,比如事 ...
- [Optimized Python] 17 - Performance bottle-neck
前言 对于一门编程语言,没接触到“优化”和“库代码”的源码理解程度,不足以谈“掌握”二字. 本篇的学习笔记,同时也意味着自己终于触及到了Python的junior国际水准.(joke) 要学的东西有很 ...
- 目标检测中常提到的IoU和mAP究竟是什么?
看完这篇就懂了. IoU intersect over union,中文:交并比.指目标预测框和真实框的交集和并集的比例. mAP mean average precision.是指每个类别的平均查准 ...
- 深入理解perf报告中的swapper进程
一.前言 1.在perf监控进程的系统调用时,会出现大量swapper进程 2.官方描述该进程是当CPU上没有其他任务运行时,就会执行swapper.换句话说swapper意味着CPU啥事也没干,跑去 ...
- 利用Python制作二维码
利用简单的Python代码制作二维码 一.制作工具 安装Python环境 + PyCharm编译器. 二.电脑系统 本人win10 + Python3.7.0 + PyCharm. 三.写代码前先下载 ...