上次说道了创建完成维护管道的Application对象,今天接着往下走;
当程序拿到维护管道的Application对象后,就开始执行管道中的23个事件了,但是微软默认给我们开发人员提供了19个可以注册的事件,在这19个事件中我们可以对,HttpContext进程一系列的处理,及其做一些条件过滤
其实HttpApplication自身并不知道传送进来的数据,他仅仅是一个通信对象,通过事件来进行交互。他触发事件,并且将信息通过HttpContext对象传递到被调用的方法中。当前请求的状态数据存储在我们前面提到的Httpcontext对象。它提供了所有请求的数据,并且在管道中,伴随着每一个请求从开始到结束。关于HttpModules
随着请求通过管道,一系列的事件在HttpApplication对象中被触发。我们已经在Global.asax中看到了这些事件。这种方法是应用程序指定的,这样,就不一定总是你想要的。如果你想创建一个广义的HttpApplication事件处理,而且能够可插拔的放到任何一个应用程序中,你可以使用HttpModules,他们是可以复用的,而且,不需要程序代码指定,只需要在web.config里面设置一下。Modules本质上像筛选器,就像一个在ASP.NET请求层的ISAPI Filter。Modules允许附加事件到每一个通过ASP.NET HttpApplication对象的请求。这些Module在外部的程序集的类里面,在web.config里面设置,并且当应用程序启动的时候,随着应用程序的启动而加载。通过实现指定的接口和方法,将事件添加到HttpApplication事件链中。多个HttpModules能够附加事件处理代码到相同的事件上,这些附加的事件处理的顺序根据在web.config里面设置的一样:<configuration>
<system.web> <httpModules> <add name= "ShopModel" type="CZBK.UI.Main.Shoper,CZBK.Shoper" /> </httpModules> </system.web></configuration>注意,你需要指定一个类型全名,还有一个程序集的名字.Modules允许你看到每一个请求并且基于触发事件形式的执行动作。Module非常适于修改request或者response的内容,用以提供定制的身份验证或者为每一个请求执行预处理。很多的ASP.NET的特性,像身份验证以及Sesion引擎都是通过HTTPModule来实现的。实现一个HTTPModule首先实现IHttpModule接口,这个接口仅仅有两个方法,Init()和Dispose().这个时间参数是一个HttpApplication对象,通过他你可以访问Httpcontext对象,在这个方法中你可以接触到HttpApplication的事件。知道了这些之后,来了解一下管道事件和页面的生成周期:
当管道中的方法一一被执行的过程中,本人用到的方法有,由于Application_Start事件是在整个网站第一次被初始化的时候被调用的,所以我们可以在这个方法中初始化一些全局的或者是静态的变量,例如网站在线人数统计使用使用到的特殊的Application对象中的值,并且在第9个事件开始获取Session的时候,如果用户已经登录,表示Session中有值,就拿到原来的Application对象中的值,并让他的值加1,并且在用户注销后,清除Session的值在第10个事件的时候让Application中的值减1,就达到的在线人数统计;有时候我们会做一些像页面静态化、或者是防止图片外链的操作,以我个人感觉这个操作越早做越好,这样发现了就直接取消这次请求,所以一般会在第一个事件BeginRequest: 开始处理请求,这个事件中进行处理,并且在第7个事件PostResolveRequestCache 已获取缓存,在第8个事件的时候要去获取一个在第11和12个事件之间执行的页面对象,所以,如果是一般的aspx这样的页面请求的话是在第8个事件的时候,并且做了判断,如果当前页面不存在,才去创建,由于他请求的是一个真实存在的页面,而在我们mvc中,请求的不是一个存在的页面,而是 控制器/Action,所以微软就在第7个事件的时候,他做了一个web.config中的映射,在这个事件中获取到了一个存在的MVCHandler对象,就不用执行第8个事件了在第11和第12个事件之间就拿到了页面对象,并且开始执行了页面的生存周期:其中拿到页面对象或者是一般处理程序,这时就会去执行他们的ProcessRequest()方法,在这个方法中首先调用了FramWorkInitializa()方法,这个方法中创建了我们页面中的所有控件树,后调用了ProcessRequestMain()方法页面生成周期的开始,首先判断了一下是不是回发过来的DeteminIspostBack() 后调用了Init方法,在其中加载了母板和主题,然会判断是不是回发IspostBack,并且执行LoadAllViewstatu()方法,加载所有的viewstatue中控件的值,其实是看一下页面中的控件的是有没有变化,把变化的控件的ID,进行base64编码后序列化成pear对象放到viewstaue中,并且准备调用控件中的所有的方法;其后执行了给控件树中的控件递归赋值的操作ProcessLoadData(),后就调用了页面的Load方法执行,并且处理了一下viewstatue,在给开发人员一次机会去改变窗体中控件的值,然后触发控件的响应事件完成后(按钮的点击事件等),页面加载完成后,递归调用了控件的渲染前事件,并且保存了viewstatue,最后将页面rande渲染成了html页面,卸载所有控件UNload,完成页面的生成周期后,执行完管道的后面几个事件,并且把渲染的html页面一级一级的往上传递最终发送给服务器端,完成一次请求!