深入了解ASP.NET运行内幕

做事情要知道根本所在,原理所在,写程序更应该知道程序的运行机制,本文主要介绍 asp.net的运行内幕
HttpApplication触发事件来通知你的程序有事发生,以此来负责请求流转.这作为HttpApplication.Init()函数的一部分发生(用Reflector查看System.Web.HttpApplication.InitInternal()方法和HttpApplication.ResumeSteps()方法来了解更多详情),连续设置并启动一系列事件,包括执行所有的处理器(handler).这些事件处理器映射到global.asax中自动生成的哪些事件中,同时它们也映射到所有附加的HttpModule(它们本质上是HttpApplication对外发布的额外的事件接收器(sink)).

HttpModule和HttpHandler两者都是根据Web.config中对应的配置被动态载入并附加到事件处理链中.HttpModule实际上是事件处理器,附加到特殊的HttpApplication事件上,然而HttpHandler是用来处理”应用级请求处理”的终点.

HttpModule和HttpHandler两者都是在HttpApplication.Init()函数调用的一部分中被载入并附加到调用链上.图6显示了不同的事件,它们是何时发生的以及它们影响管道的哪一部分.

图6-事件在ASP.NET http管道中流转的过程.HttpApplication对象的事件驱动请求在管道中流转.Http Module可以拦截这些事件并覆盖或者扩展现有的功能.

HttpContext, HttpModules 和 HttpHandlers

<script language="JavaScript" src="http://book.book560.com/ads/ads728x15.js" type="text/javascript"></script>

httpApplication它本身对发送给应用程序的数据一无所知-它只是一个通过事件来通讯的消息对象.它触发事件并通过HttpContext对象来向被调用函数传递消息.实际的当前请求的状态数据由前面提到的HttpContext对象维护.它提供了所有请求专有的数据并从进入管道开始到结束一直跟随请求.图7显示了ASP.NET管道中的流程.注意上下文对象(即HttpContext),这个从请求开始到结束一直都是你”朋友”的对象,可以在一个事件处理函数中保存信息并在以后的事件处理函数中取出.

一旦管道被启动,HttpApplication开始象图六那样一个个的触发事件.每个事件处理器被触发,如果事件被挂接,这些处理器将执行它们自己的任务.这个处理的主要任务是最终调用挂接到此特定请求的HttpHandler.处理器(handler)是ASP.NET请求的核心处理机制,通常也是所有应用程序级别的代码被执行的地方.记住ASP.NET页面和Web服务框架都是作为HttpHandler实现,这里也是处理请求的的核心之处.模块(module)趋向于成为一个传递给处理器(handler)的上下文的预处理或后处理器.ASP.NET中典型的默认处理器包括预处理的认证,缓存以及后处理中各种不同的编码机制.

有很多关于HttpHandler和HttpModule的可用信息,所以为了保持这篇文章在一个合理的长度,我将提供一个关于处理器的概要介绍.

HttpModule

 

当请求在管道中传递时,HttpApplicaion对象中一系列的事件被触发.我们已经看到这些事件在Global.asax中作为事件被发布.这种方法是特定于应用程序的,可能并不总是你想要的.如果你要建立一个通用的可用被插入任何Web应用程序的HttpApplication事件钩子,你可用使用HttpModule,这是可复用的,不需要特定语应用程序代码的,只需要web.config中的一个条目.

模块本质上是过滤器(fliter)-功能上类似于ISAPI过滤器,但是它工作在ASP.NET请求级别上.模块允许为每个通过HttpApplication对象的请求挂接事件.这些模块作为外部程序集中的类存贮.,在web.config文件中被配置,在应用程序启动时被载入.通过实现特定的接口和方法,模块被挂接到HttpApplication事件链上.多个HttpModule可用被挂接在相同的事件上,事件处理的顺序取决于它们在Web.config中声明的顺序.下面是在Web.config中处理器定义.

<configuration>

  <system.web>

    <httpModules>

  <add name= "BasicAuthModule"

      type="HttpHandlers.BasicAuth,WebStore" />

    </httpModules>

  </system.web>

</configuration>

注意你需要指定完整的类型名和不带dll扩展名的程序集名.

模块允许你查看每个收到的Web请求并基于被触发的事件执行一个动作.模块在修改请求和响应数据方面做的非常优秀,可用为特定的程序提供自定义认证或者为发生在ASP.NET中的每个请求增加其他预处理/后处理功能.许多ASP.NET的功能,像认证和会话(Session)引擎都是作为HttpModule来实现的.

虽然HttpModule看上去很像ISAPI过滤器,它们都检查每个通过ASP.NET应用的请求,但是它们只检查映射到单个特定的ASP.NET应用或虚拟目录的请求,也就是只能检查映射到ASP.NET的请求.这样你可以检查所有ASPX页面或者其他任何映射到ASP.NET的扩展名.你不能检查标准的.HTM或者图片文件,除非你显式的映射这些扩展名到ASP.NET ISAPI dll上,就像图1中展示的那样.一个常见的此类应用可能是使用模块来过滤特定目录中的JPG图像内容并在最上层通过GDI+来绘制’样品’字样.

实现一个HTTP模块是非常简单的:你必须实现之包含两个函数(Init()和Dispose())的IHttpModule接口.传进来的事件参数中包含指向HTTPApplication对象的引用,这给了你访问HttpContext对象的能力.在这些方法上你可以挂接到HttpApplication事件上.例如,如果你想挂接AuthenticateRequest事件到一个模块上,你只需像列表5中展示的那样做

列表5:基础的HTTP模块是非常容易实现的

public class BasicAuthCustomModule : IHttpModule

{

<script language="JavaScript" src="http://book.book560.com/ads/ads728x15.js" type="text/javascript"></script>

    public void Init(HttpApplication application)

    {

       // *** Hook up any HttpApplication events

       application.AuthenticateRequest +=

                new EventHandler(this.OnAuthenticateRequest);

    }

    public void Dispose() { }

    public void OnAuthenticateRequest(object source, EventArgs eventArgs)

    {

       HttpApplication app = (HttpApplication) source;

       HttpContext Context = HttpContext.Current;

       … do what you have to do…                        }

}

记住你的模块访问了HttpContext对象,从这里可以访问到其他ASP.NET管道中固有的对象,如请求(Request)和响应(Response),这样你还可以接收用户输入的信息等等.但是记住有些东西可能是不能访问的,它们只有在处理链的后段才能被访问.

你可以在Init()方法中挂接多个事件,这样你可以在一个模块中实现多个不同的功能.然而,将不同的逻辑分到单独的类中可能会更清楚的将模块进行模块化(译注:这里的模块化和前面的模块没有什么关系)在很多情况下你实现的功能可能需要你挂接多个事件-例如一个日志过滤器可能在BeginRequest事件中记录请求开始时间,然后在EndRequest事件中将请求结束写入到日志中.

注意一个HttoModule和HttpApplication事件中的重点:Response.End()或HttpApplication.CompleteRequest()会在HttpApplication和Module的事件链中”抄近道”.看”注意Response.End()”来获得更多信息.

<script language="JavaScript" src="http://book.book560.com/ads/ads728x15.js" type="text/javascript"></script>

注意Response.End()

当创建HttpModule或者在Global.asax中实现事件钩子的时候,当你调用Response.End或 Appplication.CompleteRequest的时候要特别注意.这两个函数都结束当前请求并停止触发在HTTP管道中后续的事件,然后发生将控制返回到Web服务器中.当你在处理链的后面有诸如记录日志或对内容进行操作的行为时,因为他们没有被触发,有可能使你上当.例如,sample中logging的例子就会失败,因为如果调用Response.End()的话,EndRequest事件并不会被触发.

最新版本地址: http://download.csdn.net/source/823721 演示地址: http://netfocus.b13.cnwg.cn/ 核心功能介绍  论坛前台: 1. 用户注册、登陆、注销; 2. 版块导航:显示所有的版块分组和版块; 3. 帖子列表:显示当前版块下所有的帖子,可以区分置顶帖子、精华帖子、推荐帖子; 4. 帖子内容:显示帖子内容; 5. 帖子回复:显示帖子的回复列表; 6. 添加帖子:用户添加新帖; 7. 添加回复:用户添加回复; 8. 精华帖子列表:显示所有的精华帖子; 9. 推荐帖子列表:显示所有的推荐帖子; 10. 帖子管理:具有帖子管理权限的人对帖子进行管理; 11. 回复管理:具有帖子回复管理权限的人对帖子回复进行管理;  论坛后台: 1. 版块组管理:添加、删除、修改; 2. 版块管理:添加、删除、修改,添加或修改时通过下拉框选择版块组; 3. 版主管理:可以管理论坛中每个版块的版主,如添加、删除版主; 4. 用户管理:查看用户资料、删除用户、封锁用户、解锁用户、重置密码; 5. 角色管理:添加、删除、修改; 可以定义如下角色: 系统管理员、用户管理员、角色管理员、版块管理员、版主管理员、版主、Owner、注册用户、所有人;其中Owner指发帖人,回复人;另外系统管理员、注册用户、所有人是内置角色,不能修改或删除;下面分别对每种角色的含义进行说明: 1) 系统管理员:拥有论坛所有权限; 2) 用户管理员:拥有用户管理权限; 3) 角色管理员:拥有角色管理权限; 4) 版块管理员:拥有版块管理权限; 5) 版主管理员:拥有版主管理权限; 6) 版主:拥有所有论坛事务管理权限; 7) Owner:拥有对自己发表的帖子或回复的内容进行修改的权限;(此角色可以考虑禁用,出于数据真实性考虑,因为任何人都要对他或她所说的言行负责,不允许随便修改); 8) 注册用户:拥有一部分论坛事务,如看帖,发帖,回帖,管理和自己相关的一些帖子; 9) 所有人:这个角色只是一个映射角色,任何登陆网站的人都自动拥有此角色;此角色可以表示匿名用户;仅拥有此角色的人一般只能看帖,不能做其他任何事情。当然如果愿意,我们也可以给它分配更多的权限,如发帖,回帖。如果这样,那就意味着运行匿名用户发帖或回帖了。 6. 用户角色管理:对任意一个用户的所属角色进行管理(包括添加和删除用户所属角色); 7. 角色权限管理:分为两类进行管理; 系统管理权限:用户管理、角色管理、版块管理、版主管理; 论坛事务管理权限:浏览帖子、发表帖子、修改帖子内容,修改帖子类型(包括设置为置顶帖子、推荐帖子或精华帖子)、删除帖子、移动帖子(就是从一个版块移动到另外一个版块)、修改回复、删除回复; 因为权限分为两种,所以角色权限管理也可以采用两个界面实现。这两个界面的行就是所有角色,列就是当前权限类型下的所有权限点。 8. 头像设置:设置用户的头像; 9. 密码修改; 10. 我的帖子管理:有我发布的帖子,我回复的帖子; 有一点需要在说明一下,就是版主管理模块如何实现呢? 我觉得可以这样实现: 首先定位到某个版块,然后点击版主设置,然后在出来的页面中可以把所有有版主角色的用户显示出来,比如用CheckBox显示。然后如果你想让谁做当前版块的版主,就打勾。然后保存就行。这样一来,被打勾的用户就是该版块的版主了。同一用户可以同时为多个版块的版主; 另外,一个论坛可能还常常有星级评定,积分设置,界面管理,等等其他辅助功能。这些东西可以在日后慢慢补充。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值