asp.net第二天 iis内部机制与一般处理程序

http://www.cnblogs.com/wupeiqi/archive/2013/03/10/2952214.html


http://blog.csdn.net/sundacheng1989/article/details/9995263

通信处理过程:

当服务器运行正常的情况下,客户端(浏览器)
向服务器端发送请求时,服务器端负责监听的套接字(socket),监听到有连接请求后,会为该客户端建立一个用于通信的套接字与客户端进行通信。当用户在浏览器向服务器发送请求时,浏览器会按照双方都约定好的网络传输层http协议,将请求转换成符合Http协议的请求报文。然后通过设备按照TCP协议发送到服务器。在服务器端接收到请求报文后。会按照Http协议对报文进行解析。若请求的内容为静态的数据,服务器端直接将被请求的数据,按照Http协议生成响应报文后返回给浏览器。浏览器然后解析收到的报文。将页面显示到浏览器窗口。(注:最开始仅是显示一个html 框架。经过多次请求。将CSS样式,图片………逐一的加载进来形成一个完整的页面。这个过程,有多次的交互通信。当通信结束后会把用来通信的套接字销毁,因为http协议是一种无状态的通信。这样减轻了服务器的压力)

当浏览器向客户端发送的请求为动态的。那么服务器(IIS)发现处理不了这种后缀名的文件时,会通过映射表到。响应实现了接口的可扩展程序asp.net_isapi.dll, 然后asp.net_isapi.dll,又将请求转交给网站程序处理.网站程序调用

httpRuntime类的processRequest方法来处理:

1.此类会分析接收到的请求报文.将请求报文封装到名称为httpWorkerRequest的类的属性中(便于其它地方以用).

2.创建HttpContext对象.这个对象是当前所请求报文的上下文环境.它包含了所有的请求数据.其中有两个最重要类的对象:http.Request和http.Response.  在httpRequest对象中又包含了两个属性.Form(通过表单请求的数据参数).Querystring(通过URL传递的数据参数); 通过索引器,可以找到参数的值. 在httpResponse 对象中有一个TextWriter对象.在它里面保存的是被请求的页面在执行过程中要向浏览器输出的数据.可以通过write 方法对其进行输出给浏览器。

3.通过HttpApplicationFactory类的的一个静态方法。来为每个请求创建一个单独的httpApplication对象。在创建之前HttpApplicationFactor会到HttpApplication池中查看,有没有空闲的。若有直接用。没有的时候才创建新的HttpApplication。

4.在httpApplication里运行己转换成接口IhttpHandler 的通过反射被请求页面对象的ProcessRequest 方法.

方法执行过程如下先执行httpApplication中的processRequest方法。在此方法中包含了要按照先后顺序执行的19个委托事件 当在执行到第8个事件的时候就开始创建被请求页面对象,在执行到第11和第12个事件之间时。就执行被创建的请求页面对象的ProcessRequest方法。

 

 

(二)开始页面生命周期

1.页面生命周期的主要阶段包括: 阶段 事件/方法   
页面初始化          Page_Init  
加载View State      LoadViewState   
回发数据处理      LoadPostData   
页面加载          Page_Load   
回发通知          RaisePostDataChangedEvent  
回发事件处理     RaisePostBackEvent  
页面预渲染       Page_PreRender   
保存             viewstate SaveViewState   
Page渲染         Page_Render   
Page 卸载       Page_UnLoad  

2.页面生命周期的主要事件:

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事件直到页面和所有的子控件被加载完成。这个事件主要用来设置控件属性的值,建立数据库连接(通常不这么做)。

Validation: 如果你的控件要求验证,验证会在这个阶段发生,这个时候你可以检查控件的IsValid属性。跟这个阶段关联的事件是Validate,它有一个可以接受验证字符串群的重载方法(overload method),这个重载方法执行特定控件群的验证。

Control events: 这个就不多说了,主要是处理控件的事件,例如click。这也就让我们明白了每次我们click一个Button的时候,实际上是要先去执行load事件然后才执行click事件的,一般我们用!IsPostBack来判断一下从而避免执行不必要的加载逻辑。

LoadComplete: 页面所有的控件都被加载以后执行,暂时没有想到用来干什么。。。

PreRender: 在HTML被生成之前这是最后一个事件。每一个页面中的控件都有PreRender的过程。在这里对将要输出的HTML结果进行最后一次修改。

SaveStateComplete: 在这个时间发生之前,已经保存了所有控件和页面的,任何对page或者控件的改动都不会产生左右。暂时没想到用来干啥。

Render: 它不是一个事件而是一个方法。工作就是把HTML写回客户端浏览器。

UnLoad: 页面中的每一个控件都会发生这件事。在控件中,使用这个事件来做清理工作,例如关闭数据库连接等。对与页面本身也是做清理工作,例如关闭打开的文件和数据库连接,或者结束日志或者其它指定的工作。

需要说明的是,每次Request都会创建一个全新的Page类的实例,所以在页面中的自己定义的字段是不能在两次request中传递值的,需要使用viewstate来存储。

页面处理的整体过程图解

 ----------------------------------------------此图可以直观的看出执行过程----------------------------------------

 

 

 

更详细的过程可以从阳阳多在博客中发表的用三张图片详解Asp.Net 全生命周期 一文中详读

下面我们使用三张图片解析ASP.net的整个生命周期,我总感觉使用图片更加的清楚的说明这种问题,所以使用的这样方式

 

说明:

1  第一张图片从全局说明从客户端发出一个Request请求,服务器windows内核中的HTTP.SYS组件接收该请求开始到IIS处理完该请求并响应到客户端结束。

2  第二张图片为图1中Http处理管线的详细步骤

3  第三张图片为图2Http处理管线中调用处理程序(HttpHandler,  此处为Page对象)的详细生命周期过程。

 

 

图1:


 

 

 

图2:  Http处理管线详解


 

图3:  Asp.Net生命周期详解


 


一:iis机制原理

1.浏览器将请求封装成Socket发送到iis

2.iis分为内核模式和用户模式

2.1.内核模式 HTTP.SYS 的内置驱动程序来监听来自外部的 HTTP请求。在操作系统启动的时候,IIS首先在HTTP.SYS中注册自己的虚拟路径

2.2..用户模式有httpadmin

http的请求和响应过程-----管道

以IIS 6.0为例,在工作进程w3wp.exe中,利用aspnet_isapi.dll加载.NET运行时(如果.NET运行时尚未加载),IIS 6.0引入了应用程序池的概念,一个工作进程对应着一个应用程序池。一个应用程序池可以承载一个或多个Web应用,每个Web应用映射到一个IIS虚拟目录。与IIS 5.x一样,每一个Web应用运行在各自的应用程序域中。

如果HTTP.SYS接收到的HTTP请求是对该Web应用的第一次访问,在成功加载了运行时后,会通过AppDomainFactory为该Web应用创建一个应用程序域,随后一个特殊的运行时IsapiRuntime被加载。IsapiRuntime定义在程序集System.Web中,对应的命名空间为System.Web.Hosting,被加载的IsapiRuntime会接管该HTTP请求。

IsapiRuntime会首先创建一个IsapiWorkerRequest对象,用于封装当前的HTTP请求,并将该IsapiWorkerRequest对象传递给ASP.NET运行时HttpRuntime。从此时起,HTTP请求正式进入了ASP.NET管道。HttpRuntime会根据IsapiWorkerRequest对象创建用于表示当前HTTP请求的上下文(Context)对象HttpContext。

随着HttpContext被成功创建,HttpRuntime会利用HttpApplicationFactory创建新的或获取现有的HttpApplication对象。实际上ASP.NET维护着一个HttpApplication对象池,HttpApplicationFactory从池中选取可用的HttpApplication用于处理HTTP请求,处理完毕后将其释放到对象池中。HttpApplicationFactory负责处理当前的HTTP请求。

在HttpApplication初始化过程中,会根据配置文件加载并初始化相应的HttpModule对象。对于HttpApplication来说,在它处理HTTP请求的不同阶段会触发不同的事件(Event),而HttpModule的意义在于通过注册HttpApplication的相应的事件,将所需的操作注入整个HTTP请求的处理流程。ASP.NET的很多功能,比如身份验证、授权、缓存等,都是通过相应的HttpModule实现的。

最终完成对HTTP请求的处理实现在HttpHandler中。对于不同的资源类型,具有不同的HttpHandler。比如.aspx页面对应的HttpHandler为System.Web.UI.Page,WCF的.svc文件对应的HttpHandler为System.ServiceModel.Activation.HttpHandler。上面整个处理流程如图1-11所示。


 

HttpApplication

HttpApplication是整个ASP.NET基础架构的核心,它负责处理分发给它的HTTP请求。由于一个HttpApplication对象在某个时刻只能处理一个请求,只有完成对某个请求的处理后,HttpApplication才能用于后续的请求的处理,所以ASP.NET采用对象池的机制来创建或获取HttpApplication对象。

当第一个请求抵达时,ASP.NET会一次创建多个HttpApplication对象,并将其置于池中,选择其中一个对象来处理该请求。处理完毕后,HttpApplication不会被回收,而是释放到池中。对于后续的请求,空闲的HttpApplication对象会从池中取出,如果池中所有的HttpApplication对象都处于繁忙的状态,ASP.NET会创建新的HttpApplication对象。

HttpApplication处理请求的整个生命周期是一个相对复杂的过程,在该过程的不同阶段会触发相应的事件。我们可以注册相应的事件,将处理逻辑注入到HttpApplication处理请求的某个阶段。表1-1按照实现的先后顺序列出了HttpApplication在处理每一个请求时触发的事件名称。

表1-1  HttpApplication事件列表

 

名    称 描    述
BeginRequest HTTP管道开始处理请求时,会触发BeginRequest事件
AuthenticateRequest,PostAuthenticateRequest ASP.NET先后触发这两个事件,使安全模块对请求进行身份验证
AuthorizeRequest,PostAuthorizeRequest ASP.NET先后触发这两个事件,使安全模块对请求进程授权
ResolveRequestCache,PostResolveRequestCache ASP.NET先后触发这两个事件,以使缓存模块利用缓存的内容对请求直接进行响应(缓存模块可以将响应内容进行缓存,对于后续的请求,直接将缓存的内容返回,从而提高响应能力)
PostMapRequestHandler 对于访问不同的资源类型,ASP.NET具有不同的HttpHandler对其进行处理。对于每个请求,ASP.NET会通过扩展名选择匹配相应的HttpHandler类型,成功匹配后,该实现被触发
AcquireRequestState,PostAcquireRequestState ASP.NET先后触发这两个事件,使状态管理模块获取基于当前请求相应的状态,如SessionState
PreRequestHandlerExecute,PostRequestHandlerExecute ASP.NET最终通过与请求资源类型相对应的HttpHandler实现对请求的处理,在实行HttpHandler前后,这两个实现被先后触发
ReleaseRequestState,PostReleaseRequestState ASP.NET先后触发这两个事件,使状态管理模块释放基于当前请求相应的状态
UpdateRequestCache,PostUpdateRequestCache ASP.NET先后触发这两个事件,以使缓存模块将HttpHandler处理请求得到的内容得以保存到输出缓存中
LogRequest,PostLogRequest ASP.NET先后触发这两个事件为当前请求进行日志记录
EndRequest 整个请求处理完成后,EndRequest事件被触发

对于一个ASP.NET应用来说,HttpApplication派生于Global.asax文件,我们可以通过创建global.asax文件对HttpApplication的请求处理行为进行定制。Global.asax采用一种很直接的方式实现了这样的功能,这种方式不是我们常用的方法重写或事件注册,而是直接采用方法名匹配。在Global.asax中,我们按照“Application_{Event Name}”这样的方法命名规则进行事件注册。比如Application_BeginRequest方法用于处理HttpApplication的BeginRequest事件。如果通过VS创建一个Global.asax文件,将采用如下的默认定义。
<%@ Application Language="C#" %>
<script runat="server">
    void Application_Start(object sender, EventArgs e){}   
    void Application_End(object sender, EventArgs e){}       
    void Application_Error(object sender, EventArgs e){}
    void Session_Start(object sender, EventArgs e){}
    void Session_End(object sender, EventArgs e){}
</script>
HttpModule

ASP.NET拥有一个具有高度可扩展性的引擎,并且能够处理对于不同资源类型的请求,那么是什么成就了ASP.NET的高可扩展性呢? HttpModule功不可没。

当请求转入ASP.NET管道时,最终负责处理该请求的是与请求资源类型相匹配的HttpHandler对象,但是在Handler正式工作之前,ASP.NET会先加载并初始化所有配置的HttpModule对象。HttpModule在初始化的过程中,会将一些功能注册到HttpApplication相应的事件中,在HttpApplication请求处理生命周期中的某个阶段,相应的事件会被触发,通过HttpModule注册的事件处理程序也得以执行。

所有的HttpModule都实现了具有如下定义的System.Web.IHttpModule接口,其中Init方法用于实现HttpModule自身的初始化,该方法接受一个HttpApplication对象,有了这个对象,事件注册就很容易了。
public interface IHttpModule
{
    void Dispose();
    void Init(HttpApplication context);
}

ASP.NET提供的很多基础功能都是通过相应的HttpModule实现的,下面列出了一些典型的HttpModule。

OutputCacheModule:实现了输出缓存(Output Caching)的功能。

SessionStateModule:在无状态的HTTP协议上实现了基于会话(Session)的状态。

WindowsAuthenticationModule+FormsAuthenticationModule+PassportAuthentication Module:实现了Windows、Forms和Passport这3种典型的身份认证方式。

UrlAuthorizationModule + FileAuthorizationModule:实现了基于URI和文件ACL(Access Control List)的授权。

除了这些系统定义的HttpModule之外,我们还可以自定义HttpModule,通过Web.config可以很容易地将其注册到Web应用中。

HttpHandler

对于不同资源类型的请求,ASP.NET会加载不同的Handler来处理,也就是说.aspx 页面与.asmx web 服务对应的Handler是不同的。所有的HttpHandler都实现了具有如下定义的接口System.Web.IHttpHandler,方法ProcessRequest提供了处理请求的实现。
public interface IHttpHandler
{  
    void ProcessRequest(HttpContext context);
    bool IsReusable { get; }
}

某些HttpHandler具有一个与之相关的HttpHandlerFactory,它实现了具有如下定义的接口System.Web.IHttpHandlerFactory,方法GetHandler用于创建新的HttpHandler,或者获取已经存在的HttpHandler。
public interface IHttpHandlerFactory
{
    IHttpHandler GetHandler(HttpContext context, string requestType,
      string url, string pathTranslated);
    void ReleaseHandler(IHttpHandler handler);
}

HttpHandler和HttpHandlerFactory的类型都可以通过相同的方式配置到Web.config中。下面一段配置包含对.aspx、.asmx和.svc这3种典型的资源类型的HttpHandler配置。
<configuration>
  <system.web>
    <httpHandlers>
      <add path="*.svc"
            verb="*"
            type="System.ServiceModel.Activation.HttpHandler,
                    System.ServiceModel, Version=4.0.0.0, Culture=neutral,
                    PublicKeyToken=b77a5c561934e089"
            validate="false"/>
      <add path="*.aspx"
            verb="*"
            type="System.Web.UI.PageHandlerFactory"
            validate="true"/>
      <add path="*.asmx"
            verb="*"
            type="System.Web.Services.Protocols.WebServiceHandlerFactory,
                    System.Web.Services, Version=4.0.0.0, Culture=neutral,
                    PublicKeyToken=b03f5f7f11d50a3a"
            validate="False"/>
    </httpHandlers>
  </system.web>
</configuration>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值