在之前的三篇文章中,我们还算简明扼要的学习了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. 在Ubuntu下安装ovs-dpdk

    在Ubuntu下安装ovs-dpdk 参考资料:https://software.intel.com/zh-cn/articles/using-open-vswitch-with-dpdk-on-ub ...

  2. 程序员装B指南

    一.准备工作 "工欲善其事必先利其器." 1.电脑不一定要配置高,但是双屏是必须的,越大越好,能一个横屏一个竖屏更好.一个用来查资料,一个用来写代码.总之要显得信息量很大,效率很高 ...

  3. caffe的python接口学习(7):绘制loss和accuracy曲线

    使用python接口来运行caffe程序,主要的原因是python非常容易可视化.所以不推荐大家在命令行下面运行python程序.如果非要在命令行下面运行,还不如直接用 c++算了. 推荐使用jupy ...

  4. 我的MYSQL学习心得(十三) 权限管理

    我的MYSQL学习心得(十三) 权限管理 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) ...

  5. ASP.NET 中的 Async/Await 简介

    本文转载自MSDN 作者:Stephen Cleary 原文地址:https://msdn.microsoft.com/en-us/magazine/dn802603.aspx 大多数有关 async ...

  6. 猫哥网络编程系列:详解 BAT 面试题

    从产品上线前的接口开发和调试,到上线后的 bug 定位.性能优化,网络编程知识贯穿着一个互联网产品的整个生命周期.不论你是前后端的开发岗位,还是 SQA.运维等其他技术岗位,掌握网络编程知识均是岗位的 ...

  7. 探索C#之系列目录导航

    1. 探索c#之函数创建和闭包 2. 探索c#之尾递归编译器优化 3. 探索c#之不可变数据类型 4. 探索c#之递归APS和CPS 5. 探索c#之一致性Hash详解 6. 探索c#之微型MapRe ...

  8. ASP.NET MVC 视图(三)

    ASP.NET MVC 视图(三) 前言 上篇对于Razor视图引擎和视图的类型做了大概的讲解,想必大家对视图的本身也有所了解,本篇将利用IoC框架对视图的实现进行依赖注入,在此过程过会让大家更了解的 ...

  9. PHP Excel 下载数据,并分页下载

    直接上代码: 调用下载Excel: $total=$duoduo->count(MOD.' as a',$where); $objExcel= SelfExcelObject(); //导出 i ...

  10. div里嵌套了img 底部会出现白边

    因为img默认是按基线(baseline)对齐的.对比一下图片和右边的p, q, y等字母,你会发现这三个字母的“小尾巴”和图片下方的空白一样高.下面这张图中的黑线就是那条基线. 要去掉空格可以使用v ...