ASP.NET本质论阅读----应用程序对象

概要:应用程序对象 HttpApplication ,处理上下文对象HttpContext, Web请求处理管道, HttpApplication事件处理方式

补充:管线控制流程

   1.HttpApplication控制处理流程的推进作用

   2.HttpModule订阅事件的方式加入到请求的处理过程

   3.HttpApplication获取IHttpHandler实例,将请求的响应交给IHttpHandler来实现

   HttpApplication的产生与工作

   1. HttpApplication对象会被重用,当HttpRuntime不能从HttpApplicationFactory获取空闲的实例时,才会创建。
     2. HttpRuntime会将每个请求交给一个HttpApplication对象来处理。
     3. HttpApplication对象在初始化时负责加载全部的HttpModule。
   4. 每个HttpApplication对象会控制属于它的管线过程.

   正文

1.  HttpContext

  当请求到达Asp.net服务器之后,这个对象将被创建,用来传递处理请求的参数,请求后,对象被丢弃。提供Current静态属性

2.  HttpApplication

  HttpContext对象创建过后,HttpRuntime创建一个用于处理请求的对象HttpApplication

  HttpApplication将处理过程依次发出多个事件------处理管道

  

  由于处理管道定义多个事件,创建httpApplication需要占用更多存储空间,因此System.ComponentModel.Component类提供Events属性,类型为System.ComponentModel.EventHandlerList(线性字典),需要时才创建事件通过key保持在事件集合中。

  成员:this.Events.AddHandler(Object,Delegate)

     this.Events.RemoveHandler(Object key,Delegate)

     this.Events[Object]

  使用:protected void OnPreProcess(EventArgs e)

      {

        (this.Events[new Object()] as EventHandler)(this, e);}

    2.处理管道的顺序

      1.身份验证    AuthenticateRequest开始检查用户身份

               PostAuthenticateRequest用户身份检查完毕---通过HttpContext.User获得用户

      2.权限检查    AuthorizeRequest

               PostAuthorizeRequest-----如果没有权限,直接跳到事件EndRequest

      3.读取缓存    ResolveRequestCache

               PostResolveRequestCache

      4.没有缓存-通过处理程序,匹配处理程序   PostMapRequestHandler ----获得处理程序 HttpContext.Handler

      5.获取用户上一次请求的Session状态    PostAcquireRequestState

      6.通知程序员开始进行处理工作        PreRequestHandlerExcute

        ------处理请求程序

      7.释放状态数据              ReleaseRequestState

      8.缓存处理结果              UpdateRequestCache

      9.读写日志                LogRequest

      10.结果回应到浏览器,完成asp.net处理工作

3. HttpContext 状态管理

  在HttpApplication的处理管道中,提供User,和Handler,同时提供属性Items用来传递处理需要的参数。----基于HttpContext状态管理的传递方式,周期最短。

 

设计HttpModule的目的正是为了提供一个灵活的方法解决管线事件功能重用问题。 它采用事件(观察者)的设计模式,将某些HttpHanlder都需要的功能抽取出来, 形成不同的观察者类型,这些观察者类型可以编译成类库形式,供多个网站项目共用。 为了让ASP.NET管线更灵活,ASP.NET允许我们在web.config中自由配置需要的      HttpModule,例如:

    

4. 注册HttpApplication对象的事件 处理-----IHttpModule创建

  1.  Public interface IHttpModule

    { void Dispose();

    void Init(HttpApplication context);}

  

处理HttpApplication的PostAuthenticateRequest事件的HttpModule
public void Init(HttpApplication application)
{
    application.PostAuthenticateRequest+=new EventHandler(Application_PostAuthenticateRequest);}

  2.  注册HttpModule

    <HttpModules>

      <add name="online" type="com.aspnet.OnlineUserModules, OnlineUserModule" />

    </HttpModules>

  3.   global.asax 中自动注册HttpApplication事件

    void Application_PostAuthenticateRequest(object sender ,EventArgs e)

    //Application_事件自动注册

  实例:

  

public class SetOutputCacheModule : IHttpModule
{
    public void Init(HttpApplication app)
    {
        app.PreRequestHandlerExecute += new EventHandler(app_PreRequestHandlerExecute);
    }

    void app_PreRequestHandlerExecute(object sender, EventArgs e)
    {
        HttpApplication app = (HttpApplication)sender;

        Dictionary<string, OutputCacheSetting> settings = ConfigManager.Settings;
        if( settings == null )
            throw new ConfigurationErrorsException("SetOutputCacheModule加载配置文件失败。");

        // 实现方法:
        // 查找配置参数,如果找到匹配的请求,就设置OutputCache
        OutputCacheSetting setting = null;
        if( settings.TryGetValue(app.Request.FilePath, out setting) ) {
            setting.SetResponseCache(app.Context);
        }
    }

  4.  特殊的HttpApplication事件处理

    Application_Start  MVC RouteTable在这里创建,网站第一次请求时触发,由HttpApplicationFactory对象触发

    Application_End  

    Application_Error

    

void Application_Error(Object sender, EventArgs e)
{
    HttpServerUtility server =(sender as HttpApplicaiton).Server;
    Exception exception=server.GetLastError().InnerException;
    //针对异常的处理
    //清理这个异常
    server.ClearError();
}

    Session_Start  创建Session时触发 ------注册HttpModule的 name 就是一个Session

    Session_End  Session过期或者abondon时触发

 HttpApplication、HttpHandler、HttpModule三者关系

设计这三种类型的目的在于:
1. HttpApplication控制处理流程,在不同阶段引发不同的事件。
2. 由于请求的多样性,每个请求会由一个HttpHandler对象来处理。
3. 对于一些通用性的功能,尤其是与响应内容无关的,设计成HttpModule是最合适的。

使用HttpHandler或者HtppModule的区别

1. 如果要响应一类请求,那么就选择HttpHandler。 如ashx
2. 如果要修改或者检查所有请求(总之就是不生成响应结果),那就选择HttpModule。Init(HttpApplication app) { app.BeginRequest+=......}

posted @ 2012-12-31 15:46  RyanRuan  阅读(270)  评论(0编辑  收藏  举报
View Code