深入了解ASP.NET运行内幕
事情要知道根本所在 原理所在 写程序更应该知道程序的运行机制 本文主要介绍 的运行内幕
HttpApplication触发事件来通知你的程序有事发生 以此来负责请求流转 这作为HttpApplication Init()函数的一部分发生(用Reflector查看System Web HttpApplication InitInternal()方法和HttpApplication ResumeSteps()方法来了解更多详情) 连续设置并启动一系列事件 包括执行所有的处理器(handler) 这些事件处理器映射到global asax中自动生成的哪些事件中 同时它们也映射到所有附加的HttpModule(它们本质上是HttpApplication对外发布的额外的事件接收器(sink))
HttpModule和HttpHandler两者都是根据nfig中对应的配置被动态载入并附加到事件处理链中 HttpModule实际上是事件处理器 附加到特殊的HttpApplication事件上 然而HttpHandler是用来处理 应用级请求处理 的终点
HttpModule和HttpHandler两者都是在HttpApplication Init()函数调用的一部分中被载入并附加到调用链上 图 显示了不同的事件 它们是何时发生的以及它们影响管道的哪一部分
图 事件在ASP NET 管道中流转的过程 HttpApplication对象的事件驱动请求在管道中流转 Http Module可以拦截这些事件并覆盖或者扩展现有的功能
HttpContext HttpModules 和 HttpHandlers
Application它本身对发送给应用程序的数据一无所知 它只是一个通过事件来通讯的消息对象 它触发事件并通过HttpContext对象来向被调用函数传递消息 实际的当前请求的状态数据由前面提到的HttpContext对象维护 它提供了所有请求专有的数据并从进入管道开始到结束一直跟随请求 图 显示了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 这是可复用的 不需要特定语应用程序代码的 只需要nfig中的一个条目
模块本质上是过滤器(fliter) 功能上类似于ISAPI过滤器 但是它工作在ASP NET请求级别上 模块允许为每个通过HttpApplication对象的请求挂接事件 这些模块作为外部程序集中的类存贮 在nfig文件中被配置 在应用程序启动时被载入 通过实现特定的接口和方法 模块被挂接到HttpApplication事件链上 多个HttpModule可用被挂接在相同的事件上 事件处理的顺序取决于它们在nfig中声明的顺序 下面是在nfig中处理器定义
<configuration>
<system web>
<Modules>
<add name= BasicAuthModule
type= HttpHandlers BasicAuth WebStore />
</Modules>
</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上 就像图 中展示的那样 一个常见的此类应用可能是使用模块来过滤特定目录中的JPG图像内容并在最上层通过GDI+来绘制 样品 字样
实现一个HTTP模块是非常简单的:你必须实现之包含两个函数(Init()和Dispose())的IHttpModule接口 传进来的事件参数中包含指向HTTPApplication对象的引用 这给了你访问HttpContext对象的能力 在这些方法上你可以挂接到HttpApplication事件上 例如 如果你想挂接AuthenticateRequest事件到一个模块上 你只需像列表 中展示的那样做
列表 :基础的HTTP模块是非常容易实现的
public class BasicAuthCustomModule : IHttpModule
{
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() 来获得更多信息
注意Response End()
lishixinzhi/Article/program/net/201311/11658