另一篇另篇2

ASP.NET请求处理全过程

一个ASP.NET请求过程中,从浏览器中发出一个Web请求 到 这个请求被响应并显示在浏览器中的过程中究竟会发生哪些不同的事件,当我们进入这个事件之旅时,我们也会试着明白在请求处理的每个事件当中我们可以做什么业务逻辑处理操作。

首先把整个过程大致分成两步:

  • ASP.NET会创建一个能够处理请求的环境。换句话说,它会创建一个包含请求、响应以及上下文对象的应用程序对象来处理这个请求。
  • 一旦ASP.NET环境被创建,用户请求就会通过由modules(管道)、handlers(处理程序)和page objects(页面对象)触发的一系列事件进行处理。简而言之,我们暂且将此步称为MHPM(Module、Handler、Page和Module Event)。

ASP.NET环境的创建

  • 第一步:用户请求到达IIS后,发现处理不了这个后缀的文件,就去查找映射表。IIS首先会检查哪一个ISAPI扩展能够处理这个请求,这会取决于文件的后缀名。例如:如果请求的是一个'.aspx'的页面,那么就会被传递到'aspnet_isapi.dll'来进行处理。
  • 第二步:如果这是该网站的首次请求,那么一个称为'ApplicationManager'的类会首先创建一个该网站可以运行的应用程序域(App Domain)。正如我们所知,应用程序域隔离部署在同一台IIS服务器上的两个不同的Web应用程序。因此,即使其中一个应用程序域出现了错误,也不会影响其他应用程序域的正常运作。
    应用程序域

    .NET平台下,程序集并没有直接加载进 进程 中(传统的Win32程序是直接承载的)。.NET可执行程序承载在进程的一个逻辑分区中,术语称应用程序域(简称AppDomain)。应用程序域是.NET引入的一个新概念,它比进程所占用的资源要少,可以被看作是一个 轻量级的进程。

  • 第三步:在新创建的应用程序域中,会创建ASP.NET的宿主环境,也就是HttpRuntime对象。一旦宿主环境被创建完成,网站调用HttpRuntime类的静态方法处理请求,ASP.NET最核心的对象如HttpContextHttpRequestHttpResponse对象都会被创建好。HttpApplication对象将会被分配给一系列的ASP.NET核心对象来处理请求的页面。

    这里面主要包括:

    • 分析请求报文,并将报文数据封装到一个叫HttpWorkRequest类对象应用的属性中
    • 通过调用HttpApplicationFactory类的一个静态方法创建HttpApplication对象(这里每次HttpApplicationFactory都会到HttpApplication池中去查找,看看有没用空闲的HttpApplication对象,如果有,就直接拿来使用,否则才创建新的使用,网站针对此次请求的所有运行过程都在这个对象中完成)

      如果你的系统中存在一个global.asax文件,那么这个global.asax文件的对象也会被创建。但是,需要注意的是你的global.asax需要继承自HttpApplication类。

      global.asax

      Global.asax 文件(也称作 ASP.NET 应用程序文件)是可选文件,包含用于响应 ASP.NET 或 HttpModule 引发的应用程序级别事件的代码。(换句话说,我们可以自定义后面我们所要介绍的一些事件,因为请求处理流程会经历后面的10多个事件,我们可以写代码来自定义其中的一些事件,加一些我们想做的业务逻辑操作,比如:URL重写、身份验证、图片水印等等。)

    • 创建HttpContext对象,这个对象是当前请求的上下文环境,里面包含处理请求的所有参数数据,其中最重要的就是HttpRequest和HttpResponse对象。

      HttpRequest

      对象主要包含了所有的请求信息,这些信息来源于HttpWorkRequest对象中包含的属性:Form(客户端表单数据)、QueryString(客户端url参数)

      HttpResponse

      主要包含了TestWriter对象,用来保存页面类型执行过程中要输入给浏览器的数据

    • 因为HttpApplication里面运行IHttpHandler handler=(通过反射方式创建的被请求页面类对象) 被请求页面对象里的ProcessRequest方法,所以,需要将HttpContext对象传入到HttpApplication中来,即HttpApplication对象将会被分配给一系列的ASP.NET核心对象来处理请求的页面
  • 第四步:这时,HttpApplication开始通过HTTP管道事件、处理程序(Handlers)和页面事件来处理请求了。也就是说:它会触发 MHPM 中的事件来处理请求。

下图则形象地展示了在一个ASP.NET请求过程中的重要内部对象模型。最高层是ASP.NET运行时,它创建了一个应用程序域(AppDoamin),下层则创建了一个包含request、response以及context对象的HttpRuntime。

.NET平台处理HTTP请求的过程大致如下:

  • 1、IIS得到一个请求;
  • 2、查询脚本映射扩展,然后把请求映射到aspnet_isapi.dll文件
  • 3、代码进入工作者进程(IIS5里是aspnet_wp.exe;IIS6里是w3wp.exe),工作者进程也叫辅助进程;
  • 4、.NET运行时被加载;
  • 5、非托管代码调用IsapiRuntime.ProcessRequest()方法;
  • 6、每一个请求调用一个IsapiWorkerRequest;
  • 7、使用WorkerRequest调用HttpRuntime.ProcessRequest()方法;
  • 8、通过传递进来的WorkerRequest创建一个HttpContext对象
  • 9、通过把上下文对象作为参数传递给HttpApplication.GetApplicationInstance(),然后调用该方法,从应用程序池中获取一个HttpApplication实例;
  • 10、调用HttpApplication.Init(),启动管道事件序列,钩住模块和处理器;
  • 11、调用HttpApplicaton.ProcessRequest,开始处理请求;
  • 12、触发管道事件;
  • 13、调用HTTP处理器和ProcessRequest方法;
  • 14、把返回的数据输出到管道,触发处理请求后的事件。
  • 当客户端向Web服务器请求一个页面文件时,这个HTTP请求会被inetinfo.exe进程截获(WWW服务),它判断文件后缀,如果是*.aspx、*.asmx等,就把这个请求转交给aspnet_isapi.dll,而aspnet_isapi.dll则会通过一个Http PipeLine的管道,将这个HTTP请求发送给w3wq.exe进程,当这个HTTP请求进入w3wq.exe进程之后,Asp.Net framework就会通过HttpRuntime来处理这个HTTP请求,处理完毕后将结果返回给客户端。当一个HTTP请求被送入到HttpRuntime之后,这个HTTP请求通过HTTP管道(HttpRuntime是HTTP管道的入口)被送入到一个被称之为HttpApplication Factory的一个容器当中,而这个容器会给出一个HttpApplication实例来处理传递进来的HTTP请求,同时HttpApplication实例会创建一个HttpContext对象来记录HTTP请求的上下文,而后这个HTTP请求会依次进入到如下几个容器中:HttpModule --> HttpHandler Factory --> HttpHandler.当系统内部的HttpHandler的ProcessRequest方法处理完毕之后,整个Http Request就被处理完成了.如果想在中途截获一个HttpRequest并做些自己的处理,就应该在HttpRuntime运行时内部来做到这一点,确切的说时在HttpModule这个容器中做到这个的。

通过MHPM触发的事件处理请求

一旦HttpApplication创建好,它就开始处理请求了。它经历了三个不同的部分:HttpModulePageHttpHandler。当它经过这些部分时,它将调用不同的事件,而这些事件的逻辑处理还可以由开发者来进行扩展和增加自定义处理。

先来了解一下什么是HttpModule和HttpHandlers。他们帮助我们在ASP.NET页面处理过程的前后注入自定义的逻辑处理

他们之间主要的差别

如果你想要注入的逻辑是基于像'.aspx','.html'这样的扩展名,那么你可以使用HttpHandler。换句话说,HttpHandler是一个基于处理器的扩展。

如果你想要在ASP.NET管道事件中注入逻辑,那么你可以使用HttpModule。也可以说,HttpModule是一个基于处理器的事件。

下面是请求处理过程的逻辑流程,其中有4个重要的步骤
  • 第一步(M:HttpModule):客户端请求开始被处理。在ASP.NET引擎执行和创建HttpModule触发事件(在此过程中,你也可以注入自定义逻辑)之前,有6个事件你可以在页面对象创建之前来使用,它们分别是:BeginRequestAuthenticateRequestAuthorizeRequestResolveRequestCacheAcquireRequestState 以及 PreRequestHandlerExecute
  • 第二步(H:HttpHandler):一旦以上6个事件被触发后,ASP.NET引擎就将会调用 ProcessRequest 事件,即使你已经在项目中实现了HttpHandler。
  • 第三步(P:ASP.NET Page):一旦HttpHandler逻辑执行,ASP.NET页面对象就被创建了。而ASP.NET页面被创建,一系列的事件也会随之被触发,它们可以帮助我们自定义逻辑注入到这些事件里边。在此过程中,有6个重要事件给我们提供了占位符,以便我们在ASP.NET页面中写入逻辑,它们分别是:InitLoadValidateRenderUnload。你可以通过记住单词SILVER来记忆这几个事件,S—Start(没有任何意义,仅仅是为了形成一个单词),I(Init)、L(Load)、V(Validate)、E(Event)、R(Render)。
  • 第四步(M:HttpModule):一旦页面对象执行结束并从内存中被卸载,HttpModule提供了提交返回页面的执行事件,同样,在这些事件中也可以被注入自定义的返回处理逻辑。这里有4个重要的提交处理事件:PostRequestHandlerExecuteReleaserequestStateUpdateRequestCache以及EndRequest

下图形象地展示了上面的四个步骤:

对于执行HttpApplication的ProcessRequest方法这个过程可以看成一个管道,要先后按照顺序执行19个委托事件,其中第八个时,创建 被请求的页面对象,第11到12事件之间,执行了被创建的页面类对象的ProcessRequest方法

什么是请求管道?

请求管道就是把Application的一系列事件串联成一条线,这些事件按照排列的先后顺序依次执行,事件处理的对象包括HttpModule、HttpHandler、ASP.NET Page

熟悉请求管道实现程序运行的全过程:

  • BeginRequest:开始处理请求
  • AuthenticateRequest:授权验证请求,获取用户授权信息
  • PostAuthenticateRequest:获取成功
  • AunthorizeRequest:授权,一般来检查用户是否获得权限
  • PostAuthorizeRequest:获得授权
  • ResolveRequestCache:获取页面缓存结果
  • PostResolveRequestCache:已获取缓存
  • PostMapRequestHandler:创建页面对象
  • AcquireRequestState:获取Session-----先判断当前页面对象是否实现了IRequiresSessionState接口,如果实现了,则从浏览器发来的请求报文体中获得SessionID,并到服务器的Session池中获得对应的Session对象,最后赋值给HttpContext的Session属性
  • PostAcquireRequestState:获得Session
  • PreRequestHandlerExecute:准备执行页面对象,执行页面对象的ProcessRequest方法
  • PostRequestHandlerExecute:执行完页面对象了
  • ReleaseRequestState:释放请求状态
  • PostReleaseRequestState:已释放请求状态
  • UpdateRequestCache:更新缓存
  • PostUpdateRequestCache:已更新缓存
  • LogRequest:日志记录
  • PostLogRequest:已完成日志
  • EndRequest完成

详解ASP.NET页面事件

在上面的部分中,我们已经了解了一个ASP.NET页面请求事件的整体流程。那么,在其中一个最重要的部分就是ASP.NET页面,但是我们并没有对其进行详细讨论

每一个ASP.NET页都有2个部分:一个是在浏览器中进行显示的部分,它包含了HTML标签、viewstate形式的隐藏域 以及 在HTML input中的数据。当这个页面被提交到服务器时,这些HTML标签会被创建到ASP.NET控件,并且viewstate还会和表单数据绑定在一起。一旦你在后置代码中得到所有的服务器控件,你可以执行和写入你自己的逻辑并呈现给客户浏览器。

当页面进行回发时,如点击按钮,以上事件都会重新执行一次,这时的执行顺序为:

  • OnPreInit
  • OnInit
  • OnInitComplete
  • OnPreLoad
  • Page_Load
  • OnLoad
  • Button_Click
  • OnLoadComplete
  • OnPreRender

转载于:https://www.cnblogs.com/wwkk/p/6606623.html

ASP.Net请求小周期相关推荐

  1. [译] ASP.NET 生命周期 – ASP.NET 请求生命周期(二)

    ASP.NET 请求生命周期 全局应用类也可以用来跟踪每个独立请求的生命周期,包括请求从 ASP.NET 平台传递到 MVC 框架.ASP.NET 框架会创建一个定义在 Global.asax 文件中 ...

  2. [译] ASP.NET 生命周期 – ASP.NET 请求生命周期(四)

    不使用特殊方法来处理请求生命周期事件 HttpApplication 类是全局应用类的基类,定义了可以直接使用的一般 C# 事件.那么使用标准 C# 事件还是特殊方法那就是个人偏好的问题了,如果喜欢, ...

  3. [译] ASP.NET 生命周期 – ASP.NET 请求生命周期(三)

    使用特殊方法处理请求生命周期事件 为了在全局应用类中处理这些事件,我们会创建一个名称以 Application_ 开头,以事件名称结尾的方法,比如 Application_BeginRequest.举 ...

  4. 记不住ASP.NET页面生命周期的苦恼

    介绍 对于ASP.NET开发者,理解ASP.NET的页面生命周期是非常重要的.主要是为了搞明白在哪里放置特定的方法和在何时设置各种页面属性.但是记忆和理解页面生命周期里提供的事件处理方法(method ...

  5. 【转载】Asp.Net 全生命周期

    用三张图片详解Asp.Net 全生命周期 此文是转载阳阳多的博客内容,特此声明. 下面我们使用三张图片解析ASP.net的整个生命周期,我总感觉使用图片更加的清楚的说明这种问题,所以使用的这样方式 说 ...

  6. ASP.NET页生命周期概述

    ASP.NET页生命周期的定义,有以下8个方面:页请求,开始,页初始化,页加载,验证,回发事件,呈现,卸载. ASP.NET 页运行时,此页将经历一个生命周期,在生命周期中将执行一系列处理步骤.这些步 ...

  7. [转]ASP.NET页面生命周期描述

    ASP.NET页面生命周期描述 vigorID:Vigorcsdn 在以前写个一篇关于ASP.NET页面生命周期的草稿,最近又看了看ASP.NET,做个补充,看看页面初始过程到底是怎么样的 下面是AS ...

  8. Asp.net MVC生命周期

     Asp.net应用程序管道处理用户请求时特别强调"时机",对Asp.net生命周期的了解多少直接影响我们写页面和控件的效率.因此在2007年和2008年我在这个话题上各写了一篇文 ...

  9. .NET与java的MVC模式(3):ASP.NET 页生命周期概述

    ASP.NET 页生命周期概述 来源:MSDN ASP.NET 页运行时,此页将经历一个生命周期,在生命周期中将执行一系列处理步骤.这些步骤包括初始化.实例化控件.还原和维护状态.运行事件处理程序代码 ...

最新文章

  1. hdu1010 dfs+路径剪枝
  2. PHP-cli 日志彩色玩法 echo \033[1;33m Hello World. \033[0m \n;
  3. python错误提示库没有注册_SpringBoot实现登录注册常见问题解决方案
  4. python输出print(x+y)_Python语句序列“x='car';y=2;print(x+y)”的输出结果是() (2.0分)_学小易找答案...
  5. 计算机视觉CV中RANSAC算法的学习笔记~
  6. 如何做好大型数据中心的运维
  7. 【bzoj1449/bzoj2895】[JSOI2009]球队收益/球队预算 费用流
  8. Window10系统下通过SMB协议连接和断开资源服务器
  9. 苹果恢复出厂设置报4013错误问题
  10. win10关机后cpu风扇还在转_win10电脑关机后风扇还在一直转怎么修复
  11. 阿里云对象存储OSS中上传的资源在生成URL链接时直接在浏览器中打开而不是下载的问题解决方法
  12. 老中医根治python编码问题2
  13. 偶然发现的写参考文献的利器(超快搜索+快捷摘要总结)、文末再讲一下EndNote的使用心得
  14. 【MYSQL】学习笔记
  15. SCD-缓慢变化维-拉链表
  16. shell语法中的空格和分号,引号
  17. 天才小毒妃 第966章 不死不灭的痛苦
  18. 诚信迎考 计算机考试主题班会策划,诚信考试主题班会策划书
  19. 不是有效的win32应用程序_什么是模块,VBA各种模块的有效行为
  20. 美国NIST公布首批后量子密码标准算法

热门文章

  1. 进程死锁的危害、导致原因和解决方法
  2. mysql dump xtrabackup_MySQL--备份恢复【Mysqdump+xtrabackup(XBK)】
  3. pytorch默认初始化_“最全PyTorch分布式教程”来了!
  4. 短时能量法代码c语言,[蓝桥杯][算法提高]能量项链 (Python代码)
  5. java 99乘法表对齐_Java实现九九乘法表的完整实例(对齐版)
  6. 002_Jsp三大指令
  7. python re库函数_python re库的正则表达式学习笔记
  8. exe打包工具_pyqt5快速上手基础篇12-使用Pyinstaller打包应用程序
  9. java序列化的作用
  10. 是 String , StringBuffer 还是 StringBuilder ?