在之前的三篇文章中,我们还算简明扼要的学习了asp.net的整个生命周期,我们知道了一个Request进来以后先去ISAPI Filter,发现是asp.net程序后又ASPNET_ISAPI.dll这个ISAPI Extension来进行处理。在ASPNT_ISAPI创建了Worder Process后,在管道中经过HttpModule的处理来到HttpHander的手中。

我们知道P_Handler程序员使用“乾坤大挪移”对页面进行了处理后又通过管道中的HttpModule把response返回给了客户端。

那么,这么

l         所谓的“乾坤大挪移”到底是个什么功夫呢?

l         P_Handler又是如何被调用如何消亡的呢?

l         我们自己是否也可以创建HttpHandler呢?

l         HttpHandler和我们常用的.ashx又是什么关系呢?

我们就通过今天的简单讲述让大家对这些过程有个大致的了解。

从字面上我们也可以看出,HttpHandler就是handle http(request)的,就像程序员,就是(做)程序的人员一样,所以P_Handler就是个典型的HttpRequest处理人员。我们也知道IHttpHandler接口,它就像是一个认证,任何通过了IHttpHandler认证(实现了这个接口)的人员(handler),都可以处理HttpRequest。这个认证主要有两个内容(方法):1,ProcessRequest;2,IsReusable。

ASP.NET默认有很多个Handler,它们处理了各式各样的asp.net文件,例如.config,.cs,.aspx等等。通过路径C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG\web.config找到web.config文件我们可以发现系统预定义的httphandler,因为太多在这就不一一列举。

通过<add path="*.config" verb="*" type="System.Web.HttpForbiddenHandler" validate="true" />我们可以知道我们项目中的web.config文件为什么不能访问了,原来是被 HttpForbiddenHandler给屏蔽了,我估计它是直接返回了一个错误,这样我们就不能访问这些资源,同样的,.sitemap, .asax, ..cs, .csproj等等我们熟悉的项目中的文件都是使用HttpForbiddenHandler来屏蔽掉的。

而但是通过<add path="*.aspx" verb="*" type="System.Web.UI.PageHandlerFactory" validate="true" />我们也可以发现原来.aspx是通过PageHandlerFactory来处理的。那么PageHandlerFactory又是什么东西呢?

通过反编译PageHandlerFactory我们可以看到:

Code

这个page handler的工厂通过GetHandler得到了一个IHttpHandler,这个Handler是什么呢?答案就在GetHandlerHelper方法中:

代码

我们可以清楚的看到,这个方法返回了一个Page,wow,原来Page类就是处理.aspx文件的HttpHandler啊,看到Page类的定义:

public class Page : TemplateControl, IHttpHandler
{

}

我们更是确信无疑:System.Web.UI.Page就是处理.aspx页面的那个程序员P_Handler。这种程序员很平凡,却是不可或缺的,因为他们承担着一线的大量工作任务。而PageHandlerFactory就是专门培训这种处理页面的程序员的培训机构。这种培训机构很多,也就培养了各种各样的Handler,而我们自己也可以创建自己的培训机构,培训自己的HttpHandler,只要通过IHttpHandlerFactory这个认证(接口实现)就可以了。Page类是我们最常用的P_Handler程序员,它就像.net初级程序员一样普遍,只不过它不像我们这样什么都会,它只处理页面(因为它在一个大公司,微软啊,分工多明确啊)。

微软有程序员,我们也可以有,那么接下来我们就自己创建一个HttpHandler,我们用它来Handler我们定义的后缀名.godspeed文件。这个过程分为三步:

首先,我们创建一个实现了IHttpHandler的类

然后,在web.config文件中添加一行文字以便让server知道该如何处理.godspeed后缀名文件

最后,我们在IIS中映射我们的新后缀名到asp.net,好让IIS可以把这个文件传给ASP.NET进行处理并返回我们期望的结果。好,开始做。

1, 创建名为TestCustomHttpHandler的网站

2, 添加test.godspeed文件到网站中

3, 创建GodSpeedHttpHandler.cs文件,代码如下:

4, 配置web.config

<handlers>

<add name="GodSpeedHttpHandler" verb="*" path="*.godspeed" type="MyHandlers.GodSpeedHttpHandler "/>

</handlers>

5, 映射到IIS和asp.net

6, 访问test.godspeed

re

多简单啊 各位看官可是看明白了?不明白没关系,欢迎回复和拍砖。

而我们常用的ashx也一种非常简单的handler,它通常用来处理不需要回传的任务,比如生成动态图片等等,园子里有很多这样的示例,在这里就不详述了。

那么我们之前提到Page类只处理页面,它也是我们最最常用的,最最重要的P_Handler程序员,它究竟是如何工作呢?它的工作对我们的日常开发又有什么影响呢?在下一篇文章中我将着重讲解页面生命周期也就是Page类的ProcessRequest都引发了哪些事件以及在这些事件中我们能做些什么进行深入的探讨。

话说我们今天的重中之重:页面生命周期,说的就是Page类在处理页面的过程中都发生了哪些事件,而这些事件又是按照什么顺序发生的。ASP.NET的页面生命周期跟我们之前的理论讲解完全不同,它具有非常强大的实用性,所以我想通过一个小例子来进行解释和说明,以便让大家看起来更清晰和容易理解。因为Page类的ProcessRequest方法实现非常的复杂,我把代码反编译过来给大家看我觉得也没什么意义,所以我就着重给大家看一下整个页面的事件是以何种顺序被引发的,以及在这些事件中,我们能做什么。在这个过程中,我们主要关注如下问题:

1,    事件的执行顺序

2,    控件何时被初始化(我们什么时候能用它)

3,    ViewState何时可用

4,    更改MasterPage和Theme

5,    在各个事件中还能干什么工作

按照如下步骤建立示例:

一,我们创建一个website

二,加入两个MasterPage分别为site.master和map.master,分别在上面加一个label进行说明:this is site/map master page.

三,分别加入两个theme为BlueSkin和RedSkin,分别对button的背景色进行设置,一个是Blue,另外一个是Red

四,在default页面中加入两个label和一个button

五,Default页面代码如下:

六,执行结果:

七,代码分析

a)         从执行结果我们可以看到,事件的执行顺序为:

i.              PreInit

ii.              Init

iii.              InitComplete

iv.              PreLoad

v.              Load

vi.              Control Event(if they have)

vii.              LoadComplete

viii.              PreRender

ix.              PreRenderComplete

x.              SaveStateComplete

xi.              Render

xii.              Unload

b)         从结果中我们也可以看到,在PreInit事件发生后控件还没有被初始化,也就是我们还不能使用。而在Init刚刚发生的时候已经可以使用了。也就是说,控件初始化发生在PreInit之后Init之前。总而言之,我们关心的是我们最早可以在Init事件里对页面server端控件进行操控。

c)         关于ViewState,本示例也清晰的显示出它在Init Complete之后还是不能使用,而在PreLoad刚刚发生的时候,就已经可以使用了。

d)         通过对比Default.aspx页面的配置我们知道,在PreInit里面的Theme和MasterPage的设置是生效了的,我们可以在PreInit里设置Theme和MasterPage,而在其它任何位置设置这两个东西都将抛出异常(看我注视掉的代码)

e)         其它的事件:

Load: 这个事件可能是大家最熟悉的了。需要注意的是,Page对象会递归的调用子控件的onload事件直到页面和所有的子控件被加载完成。这个事件主要用来设置控件属性的值,建立数据库连接(通常不这么做)。

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

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

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

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

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

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

f)          关于Unload事件,它实际上做的是销毁前的工作。在Unload事件发生以后,Page类被卸载和销毁,所以page类的字段值也就消失了,而我们通常也是使用在SaveStateComplete之前保存的ViewState来存储哪些我们想要存储的page里的数据。HttpRuntime做了销毁Page的动作,同样也是它创建的Page这个handler,现在我们知道原来不是HttpApplication雇佣了P_Handler, HttpApplication只是使用了它而已,真正雇佣(创建)并解雇(销毁)P_Handler的是老板HttpRuntime。

整个ASP.NET生命周期基本结束,如果大家想更深入的了解其中内情,请反编译System.Web.HttpRuntime类。如果您不喜欢研究那么深入,我想我这几篇文章应该可以对您有些帮助。

我并不打算就此停手,接下来我还将会围绕ASP.NET生命周期和大家进一步深入探知iis6中的最重要的改进—Application Pool的奥秘和重要的HttpModule—-SessionStateModule。在这些都结束以后,我将接着跟大家学习ASP.NET在IIS7中的变化及相应的知识,欢迎大牛指导和拍砖,谢谢。

相关示例代码:

自定义HttpHandler和PageLifeCycle示例代码.zip

[转]ASP.NET应用程序生命周期趣谈(四) HttpHandler和页面生命周期的更多相关文章

  1. [转]ASP.NET应用程序生命周期趣谈(三) HttpModule

    在之前的文章中,我们提到过P_Module(HttpModule)这个能干的程序员哥们儿,它通过在项目经理HttpApplication那里得到的授权,插手整个应用程序级别的事件处理.所有的HttpM ...

  2. 一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](四)

    前言 上一篇<一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](三)>,我们完成了: * 引用SqlSugar * ...

  3. [转]ASP.NET应用程序生命周期趣谈(五) IIS7瞎说

    Ps:建议初学者在阅读本文之前,先简要了解一下之前的几篇文章,以便于熟悉本文提到的一些关于IIS6的内容,方便理解.仅供参考. PS:为什么叫瞎说呢?我觉得自己理解的并不到位,只能是作为一个传声筒,希 ...

  4. [转]ASP.NET应用程序生命周期趣谈(一)

    这几天一直在看ASP.NET应用程序生命周期,真是太难了,我理解起来费了劲了,但偏偏它又是那么重要,所以我希望能给大家带来一篇容易理解又好用的文章来帮助学习ASP.NET应用程序生命周期.这篇就是了. ...

  5. [转]ASP.NET应用程序生命周期趣谈(二)

    在上回书开始的时候我们提到博客园的IIS看了一眼我的请求后就直接交给ASP.NET去处理了,并且要求ASP.NET处理完之后返回HTML以供展示. 那么我们不仅要问: 1,    IIS肯定是没有眼睛 ...

  6. ASP.Net请求处理机制初步探索之旅 - Part 4 WebForm页面生命周期

    开篇:上一篇我们了解了所谓的请求处理管道,在众多的事件中微软开放了19个重要的事件给我们,我们可以注入一些自定义的业务逻辑实现应用的个性化设计.本篇,我们来看看WebForm模式下的页面生命周期. ( ...

  7. .net学习笔记---IIS 处理模型及ASP.NET页面生命周期

    本文是基于IIS6的处理模型. 当一个客户端页面访问IIS试图获取一些信息的时候,发生了什么事情?一个请求在通过了HTTP管道后又发生了什么?本文主要是描述这两个过程,即IIS处理asp.net请求和 ...

  8. Asp.net页面生命周期详解任我行(3)-服务器处理请求详细过程

    前言 百度了一下才知道,传智的邹老师桃李满天下呀,我也是邹老师的粉丝,最开始学习页面生命周期的时候也是看了邹老师的视频. 本人是参考了以下前辈的作品,本文中也参合了本人心得,绝非有意盗版,旨在传播,最 ...

  9. 一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](五)

    前言 Hi,大家好,我是Rector 时间飞逝,一个星期又过去了,今天还是星期五,Rector在图享网继续跟大家分享系列文本:一步一步创建ASP.NET MVC5程序[Repository+Autof ...

随机推荐

  1. 搞了我一下午竟然是web.config少写了一个点

    Safari手机版居然有个这么愚蠢的bug,浪费了我整个下午,使尽浑身解数,国内国外网站搜索解决方案,每一行代码读了又想想了又读如此不知道多少遍,想破脑袋也想不通到底哪里出了问题,结果竟然是web.c ...

  2. EasyPR--开发详解(7)字符分割

    大家好,好久不见了. 一转眼距离上一篇博客已经是4个月前的事了.要问博主这段时间去干了什么,我只能说:我去“外面看了看”. 图1 我想去看看 在外面跟几家创业公司谈了谈,交流了一些大数据与机器视觉相关 ...

  3. ABP源码分析四十五:ABP ZERO中的EntityFramework模块

    AbpZeroDbContext:配置ABP.Zero中定义的entity的Dbset EntityFrameworkModelBuilderExtensions:给PrimitiveProperty ...

  4. Entity Framework 6 Recipes 2nd Edition(13-4)译 -> 有效地创建一个搜索查询

    问题 你想用LINQ写一个搜索查询,能被转换成更有效率的SQL.另外,你想用EF的CodeFirst方式实现. 解决方案 假设你有如下Figure 13-6所示的模型 Figure 13-6. A s ...

  5. CentOS 安装OciLib 4.2.1 (Linux)

    项目要用oracle , Windows的 OciLib 好弄, 今天安装到linux下 ,编译老是出错,最后几行如下: checking for OCILIB install path... /us ...

  6. ASP.NET MVC5+EF6+EasyUI 后台管理系统(63)-Excel导入和导出

    系列目录 昨天文章太过仓促没有补充导出的示例源码,在者当时弄到到很晚没时间做出导出功能,对阅读理解造成影响,现补充一份示例源码,顺便补充导出的功能说明,望理解 示例代码下载   https://yun ...

  7. Hawk 3. 网页采集器

    1.基本入门 1. 原理(建议阅读) 网页采集器的功能是获取网页中的数据(废话).通常来说,目标可能是列表(如购物车列表),或是一个页面中的固定字段(如JD某商品的价格和介绍,在页面中只有一个).因此 ...

  8. TortoiseGit:记住用户名和密码

    1.背景: 我们在使用 tortoisegit 工具时会无可避免的经常性 pull 和 push,这时通常要输入用户名和密码,由于麻烦,就有人提出了记住用户名和密码的需求... ... 2.设置: [ ...

  9. ORACLE 11gR2 DG(Physical Standby)日常维护02

    环境:RHEL 6.5 + Oracle 11.2.0.4 三.监控DG的状态 3.1监控DG备库的状态 3.2监控主库传输日志链路的状态 四.备库切换为snapshot standby 4.1备库切 ...

  10. Windows Programming ---- Beginning Visual C#

    span.kw { color: #007020; font-weight: bold; } code > span.dt { color: #902000; } code > span. ...