IIS处理Asp.net请求和Asp.net页面生命周期方法 |
当一个客户端页面 拜访IIS试图猎取一些信息的时候, 产生了什么 事件?一个 申请在通过了HTTP管道后又 产生了什么?本文主要是 形容这两个过程,即IIS 解决asp.net 申请和asp.net的页面生命周期 。 欢送大家 踊跃拍砖,一起学习,一起 普及 。 首先我们要弄清楚两个十分主要的概念: 1, worker process(w3wp.exe). worker process治理全部的来自客户端的 申请并给出响应 。它是IIS下asp.net 利用程序的核心 。 2, application pool. 它是worker process的容器,IIS5及之前的IIS版本均没有application pool的概念 。每一个application pool对应着一个worker process,在IIS Metabase中 保护着Application Pool和worker process的Mapping 。这就幸免了IIS5中浮现的worker process(IIS5中是aspnet_wp.exe,同一 工夫不得不运行一个该 历程) 瓦解,application全 瓦解的局面 。 客户端向IIS发出一个资源 申请后 产生了如下 事件: 1, server 承受该 申请 IIS6通过内核模式(Kernel mode)中的HTTP.SYS来 散发各个Request到application pool 。 这并不是随机的过程,在application pool 缔造的时候就已经注册到了HTTP.SYS,所以当 申请来到时HTTP.SYS会直接发送到相应的application pool 。 接下来在IIS的消费者模式(User mode)中,Web Admin Services (WAS) 做了从HTTP.SYS中得到Request并 散发到application pool的工作 。application pool直接把request传递给worker process 。 2, 申请传递到worker process后,worker process初始化加载ASP.NET ISAPI(Internet Server Application Program Interface),ASP.NET ISAPI进而加载CLR 缔造托管环境 。 (注:ISAPI只不过一个接口,起到一个代理的作用,主要 威力便是依据Request URL的后缀来寻觅该后缀的 解决程序) ASP.NET ISAPI定义在aspnet_isapi.dll中,它 本身运行在一个非托管的环境中 。ASP.NET ISAPI开始一个HttpRuntime, HttpRuntime调用ProcessRequest 步骤来开始 解决 申请 。ProcessRequest依据ISAPI传进来的iWRType 来 缔造不同的HttpWorkerRequest,从而屏蔽了不同IIS的差别 。接下来ProcessRequest 步骤 缔造了HttpContext,我们 使用HTTPContext.Current来 拜访它 。在HttpRuntime 使用HttpApplicationFactory 缔造了HttpApplication对象(IHttpHandler)以后,全部的 申请都会在通过httpmodule后找到相应的Httphandler进行 解决 。在HttpApplicationFactory 缔造HttpApplication之前,会搜索config(web.config和Machine.config)文件中注册的全部的HttpModule,并依据配 相信息加载相应的Assembly,通过Reflection 缔造对应的HttpModule,并将这些Module加到HttpApplication 的_moduleCollection Filed中 。我们对一个Application的 申请最终会落到一个HttpApplication对象上 。当一个 申请到来时,ASP.NET会在Httplication Pool中搜索未被 使用的HttpApplication对象 。 3, 申请通过HTTP管道后,每个 申请都发向 有关的各自的httphandler,IIS 申请 解决过程 完毕 。 HttpHandler是HTTP管道的终点,它为每个request生成输出 。System.Web.UI.Page便是这样一个典型的Httphandler,当我们 申请一个aspx页面,这个HttpHandler就生成html发送回客户端 。看Page类的签名: public class Page : TemplateControl, IHttpHandler { } 可以看到,Page类便是一个HttpHandler 。 综上整个过程便是:当客户端向服务器发送资源 申请时, 申请首先 到达IIS的HTTP.SYS 。 而后HTTP.SYS发送 申请道对应的Application Pool 。 而后Application Pool发送 申请到Worker Process(W3WP.exe)中加载ISAPI Extension,ISAPI 缔造一个HttpRuntime对象来通过HttpModule和HttpHandler 解决 申请 。 而后页面生命周期就开始了 。 4, 页面生命周期开始 页面生命周期的主要阶段包括: 页面初始化(Init): 服务器 缔造服务器控件的实例 加载(load): 控件实例被加载到它定义的页面对象中 预输出:(PreRender) 对控件的更改被更新, 预备输出 。 保留(SaveViewState): 控件的状态信息被 保留 。 输出页面(Render):服务器为控件 缔造html标记 。 解决(Dispose): 主要做的工作便是dispose, 关闭数据库衔接,文件资源的 开释等 。 卸载(Unload):销毁服务器控件的实例 页面生命周期的主要事件: PreInit: 1. 审查IsPostBack 属性 2.动态设置Master Page 3.动态设置Theme 4.设置控件的默许值(UniqueId等) 5.再一次 缔造动态控件(初始化控件),初始化控件的值 Init: 这个事件 产生在全部的控件被初始化,全部的皮肤设置被 利用以后 。它用来读取或者初始化控件属性 。它 可以用来注册一些aspx页面中没有指出的控件的事件 。 InitComplete: Use this event for processing tasks that require all initialization to be complete. PreLoad: 加载页面的ViewState和全部的控件, 而后 解决全部的包括在Request实例中的postback数据 。 Load: 这个事件可能是大家最 相熟的了 。需求 留神的是,Page对象会递归的调用子控件的onload事件直到页面和全部的子控件被加载 实现 。这个事件主要用来设置控件属性的值, 构建数据库衔接(通常不这么做) 。 Control events: 这个就不多说了,主要是 解决控件的事件,例如click 。这也就让我们清楚了每次我们click一个Button的时候,实际上是要先去执行load事件 而后才执行click事件的,普通我们用!IsPostBack来推断一下从而幸免执行 毋庸要的加载逻辑 。 LoadComplete: 页面全部的控件都被加载以后执行,临时没有想到用来干什么 。 。 。 PreRender: 在HTML被生成之前这是最终一个事件 。每一个页面中的控件都有PreRender的过程 。在这里对将要输出的HTML 后果进行最终一次 批改 。 SaveStateComplete: 在这个 工夫 产生之前,已经 保留了全部控件和页面的,任何对page或者控件的 改变都不会产生左右 。临时没想到用来干啥 。 Render: 它不是一个事件而是一个 步骤 。工作便是把HTML写回客户端阅读器 。 UnLoad: 页面中的每一个控件都会 产生这件事 。在控件中, 使用这个事件来做清理工作,例如关闭数据库衔接等 。对与页面 本身也是做清理工作,例如关闭 打开的文件和数据库衔接,或者 完毕日志或者其它指定的工作 。 需求 注明的是,每次Request都会 缔造一个崭新的Page类的实例,所以在页面中的自己定义的字段是不能在两次request中传递值的,需求 使用viewstate来存储 。 5, HttpHandler依据页面生命周期中事件的 解决把 后果发回IIS,IIS再把 后果发回客户端阅读器 。 值得 留神的是,在这个过程中 申请会再次通过HttpModule(注册一个EndRequest事件) 。 至此,整个Request 完毕 。 |