现在的位置: 首页 > 综合 > 正文

asp.net 页面生命周期 小谈

2013年06月29日 ⁄ 综合 ⁄ 共 3490字 ⁄ 字号 评论关闭

   在前面的博客中,我讲解了 浏览器和服务器的之间请求响应过程,算是给asp.net页面生命周期的讲解进行了铺垫,接下来就重要了喔~~
   浏览器向服务器发送请求以后,服务器会根据请求的报文头判断请求的页面是动态页面还是静态页面,如果是静态页面,服务器软件就会直接读取静态页面的代码,然后返回给浏览器,不会对代码进行更多的处理;如果所请求的页面是动态页面,IIS就会发现自己处理不了这种文件,就会映射表根据请求的页面的后缀名找到响应的处理程序,即ISAPI(服务器扩展程序),让ISAPI去处理这种页面的代码。有园友会问到,IIS如何调用可扩展程序呢?
请想想,如果让我们写一个程序,如果我们所处理的页面种类很多,但都有类似的处理方法,那么我们会怎么处理?  很明显,我们可以使用接口,让所有的ISAPI实现IIS所提供的接口,然后让IIS根据不同的后缀名去调用不同的ISAPI,然后ISAPI再去和FrameWork具体商议具体的细节。
   在IIS调用了ISAPI后,ISAPI又将请求交给了网站程序,网站程序会调用HttpRuntime这个强大的类的静态方法去处理请求。
   首先,HttpRuntime这个类 会将请求的报文封装到HttpWorkRequest这个类中
   然后,HttpRuntime 会创建上写文请求对象 HttpContext,而HttpContext则封装了有关个别HTTP请求的所有HTTP特定的信息,并同时创建了两个及其重要的两个对象
   HttpRequest ----使用asp.net 能够读取客户端在Web 请求期间发送的HTTP值
   HttpResponse ----封转来自asp.net 操作的Http响应信息。
   
   如果用强大的反编译 你会看到如下一段代码
   this.Init(new HttpRequest(wr,this),new HttpResponse(wr,this))

 HttpRuntime 会调用 HttpApplicationFactory 创建一个HttpApplication 实例,将上下文请求对象的值传给HttpApplication,让        HttpApplication 去处理其中详细的请求处理,
  在微软的MSDN中,对HttpApplication进行了定义, 定义了asp.net 应用程序里所用应用程序共有的属性 方法 事件
   在反编译里 我们同样可以看到这样两句代码
   application=(HttpApplication)HttpRuntime.CreateNoPublicInstance(this._theApplicationType)
   HttpApplicationFactory.GetApplicationInstance(context)

   如果不明白,我可以再次梳理,自己也给自己梳理一次。
当HttpContext 对象创建以后,HttpRuntime将随后创建一个用于处理请求的对象,这个对象的类型是HttpApplication。
在asp.net 内部,HttpRuntime会管理一个HttpApplicationFactory类的实例,HttpApplicationFactory内部维护着一个HttpApplication对象池(请记住,池是.net中经常用到的),使得被创建的HttpApplication可以重复使用,但是每一个HttpApplication对象每一次仅仅处理一个请求,这对asp.net程序员来说是很幸福的一件事情,因为我们不需要考虑HttpApplication中多个请求并发处理的问题。

  下面这张图便是上述过程最形象的解释了

                                   

  看完上面这张图 我们再看下面这张图吧

 

                                                           

   可能你看不懂,没关系,我在下面会依次讲解每一个事件代表什么含义,不要着急喔
   最后,当这些准备都好了后,我们便正式进入了 美丽而虚幻的 asp.net页面生命周期。
   
   然后 会执行HttpRuntime的ProcessRequest() 方法,驱动所有 ASP.NET Web 处理执行。

  此时HttpApplication便发挥了它自己用处,会开始进行管线处理请求,也称为HTTP执行管道链。那么什么是管线处理请求呢。在HttpApplication中,利用 .net 的事件机制,通过在处理过程中依次发出的多个事件,将这个请求处理分成多个步骤,这个机制通常我们称为处理管道。 我们应该知道 对于有着众多事件的类来说,定义大量的事件意味着在创建这个类的时候需要付出更多创建事件的成本。微软人可不是傻子,他们有自己的解决方法,他们定义了一个EventHandlerList,一个线性字典,当需要事件的时候,就通过key将将事件放入到这个线性字典中,没有对应的事件,就不会付出成本。这样通过EventHandlerList可以在一个集合中管理多个事件对象。
  
   在HttpApplication所处理的管道链中共有19个事件,
   No.1 BeginRequest 标志着asp.net 服务器处理工作的开始
   No.2 No.3  AuthenticateRequest, PostAuthenticateRequest 这两个事件提供检查当前用户身份,前者表示开始检查用户的身份,后者表示用户身份已经检查完成,那么如何获取当前用户的身份??
   No.4,No.5 AuthorizeRequest, PostAuthorizeRequest 前者用来用来进行对用户的权限检查 后者表示完成了用户权限的检查
   No.6 No.7 ResolveRequestCache, PostResolveRequestCache  前者事件标志着从以前缓存的结果中进行检查,后者事件表示缓存检查的结果
   No.8 PostMapRequestHandler创建了请求页面类对象, 什么是Handler,Handler 就是用于处理请求以得到结果的对象称为处理程序Handler
   No.9 AcquireRequestState(当 ASP.NET 获取与当前请求关联的当前状态(如会话状态)时发生)中,asp.net应用程序会根据浏览器发送的Cookie中的SessionId去Session池找对相应的Session并赋给 context.Response.Session
   No.10 PostAcquireRequestState 表示已经完成了用户数据的获取,可以开始处理我们所需要的数据了。
   NO.11 PreRequestHandlerExecute 事件用来通知程序员,处理程序就要开始处理工作了。
   No.12 PostRequestHandlerExecute事件通知程序员,asp.net 服务器的处理程序已经完成。
   在11个事件和12个事件之间,asp.net 服务器将通过执行处理程序完成请求的处理的工作,对页面进行加工,呈现给浏览器(具体过程,请参见我的一篇博文,页面控件树的生产)。
   在处理完成之后,由于程序员可能修改了用户特定的专属数据,那么修改后用户状态数据可能需要进行序列化或者保存处理,No.13ReleaseRequestState 事件通知程序员需要释放这些状态数据,No.14 PostRealeseRequestState 则表示已经释放完成。
    在我们处理完成以后,如果希望将这次处理的数据缓存起来,以便在后继的请求中直接使用这个结果,No.15 UpdateRequestCache事件提供了处理的机会,No.16PostUpdateRequestCache 表示缓存已经更新完成。
    在asp.net4.0中新增加了两个事件完成处理日志的工作,No.17 LogRequest 表示将这次请求记入日志,No.18PostLogRequest表示完成了这次日志工作。
    而No.19 EndRequest是HttpApplication处理管道的事件,也是程序员处理的asp.net 处理请求的最后一个机会,之后,处理的结果将被回应到浏览器中,整个生命周期结束。

   我到现在为止,自认为过web请求处理管道过程弄懂了的,但在工作中还未应用,希望大侠能够指点~~

   初学者若有说错或说的不周之处,请各位指正,在下十分感激~~~
    
   
        

 

抱歉!评论已关闭.