Asp.net大文件上传(二)
吴剑 2009-04-20
转载请注明出处:http://www.cnblogs.com/wu-jian/
3. Asp.net管道
3.1 主要流程
从请求进入ASP.NET工作者进程,直至它到达最终的处理程序之前要经过一系列的步骤和过程,这个步骤和过程本文中将其称之为ASP.NET管道,关于ASP.NET管道我并未找到相关官方的标准文档,而是根据Fritz Onion的《ASP.NET基础教程》整理而来。
1、ASP.NET管道的第一步是创建HttpWorkerRequest对象,它包含与当前请求有关的所有信息,包括请求的URL、标题等等。
2、把请求传递给HttpRuntime类的静态ProcessRequest方法。
3、HttpRutime类执行的第一件事情是创建HttpContext对象,并用HttpWorkerRequest类进行初始化。HttpContext类是管道的“粘合剂”,因为它把与当前请求有关的所有信息保存在一个地方,把所有类合成一体。第一次创建HttpContext对象时,它分配HttpRequest和HttpResponse类的新实例并且字段存储它们。它还为应用程序和会话状态提供了专用的访问器。(关于HttpContext请参阅3.2节)
4、一旦创创建了HttpContext类,HttpRuntime类就通过调用HttpApplicationFactory类的静态GetApplicationInstance方法,为该应用程序请求HttpApplication派生类的一个实例。
5、GetApplicationInstance要么创建HttpApplication(或派生类)类的一个新实例,要么从应用程序对象池中拖出一个实例。(关于HttpApplication请参阅3.3节)
6、一旦创建或检索到HttpApplication类,就对它进行初始化,并在初始化期间分配为此应用程序定义的所有模块。模块是实现IHttpModule接口的类,它为进程前后的请求提供服务。
7、一旦创建了模块,HttpRuntime类通过调用它的BeginProcessRequest方法,要求最新检索到的HttpApplication类对当前请求提供服务。然后,为当前请求找到合适的处理程序工厂。
8、创建处理程序,传递当前HttpContext,一旦ProcessRequest方法返回,请求完成。
3.2. HttpContext
上下文(HttpContextAsp.net)是Asp.net管道中最重要的一个类,该类维护所有与请求有关的数据,并且可以为管道中的大多数元素所访问,在请求的生命周期里,上下文一直是有效的。并且可以通过静态的HttpContext.Current属性访问,正如它的名字暗示的那样,HttpContext对象表示当前活动请求的上下文,因为它包含了在请求生命周期里你会用到的所有必需对象的引用,如:Request,Response,Application,Server,Cache。在请求处理过程的任何时候,你都可以使用HttpContext.Current访问这些对象。记住HttpContext是你的朋友,在请求或者页面处理的不同阶段,如果你需要相关数据都可以使用它获取。
3.3. HttpApplication
HttpApplication主要用作是Asp.net管道的事件控制器,负责请求的传输,通过触发事件,通知应用程序正在发生的事情。HttpApplication本身并不知晓发送给Web程序的数据,它仅仅是个消息邮递者,只负责事件之间的通信。它触发事件,然后通过传递HttpContext对象,把信息发送给被调用的方法。Asp.net管道的事件按照顺序逐一触发事件,如下图所示:
HttpApplication向外界提供的事件
事件 | 激活原因 | 顺序 |
BeginRequest | 收到新的请求 | 1 |
AuthenticateRequest | 已经确立用户的安全身份 | 2 |
AuthorizeRequest | 已经验证用户授权 | 3 |
ResolveRequestCache | 在受权以后但是在调用处理程序之前,如果找到缓存入口,则被缓存模块用来绕过处理程序的执行。 | 4 |
AcquireRequestState | 加载会话状态 | 5 |
PreRequestHandlerExecute | 请求发送到处理程序之前 | 6 |
PostRequestHandlerExecute | 请求发送到处理程序之后 | 7 |
ReleaseRequestState | 所有请求处理程序完成以后,被状态模块用来保存状态数据 | 8 |
UpdateRequestCache | 处理程序执行以后,被缓存模块用来存储缓存中的响应 | 9 |
EndRequest | 请求被处理以后 | 10 |
Disposed | 正好在关闭应用程序之前 | |
Error | 出现一个未经处理过的应用程序错误时 | |
PreSendRequestContent | 内容发送到客户之前 | |
PreSendRequestHeaders | HTTP标题发送到客户之前 |
3.4. IHttpModule
模块(HttpModule)是功能最强大的扩展点,它们在第一次创建应用程序时被创建,并且在应用程序的生命期内一直存在,可以接进任何一个HttpApplication事件。通常用于执行请求的预处理和后加工,在许多方面类似于IIS中的ISAPI过滤器。ASP.NET本身就用模块实现了许多应用程序级功能,包括身份验证、授权、缓存、及进程外会话状态管理。
如下示例了一个HttpModule的实现:
web.config
3.5. IHttpHandler
web.config
从如上代码可以发现,实现一个HttpHandler看似非常简单,它仅仅包含一个ProcessRequest()方法和一个IsReusable属性。但真是如此简单吗?记住,WebForms和WebServices都是作为HttpHandler实现的,在这个看似简单的接口里,其实很多的实现过程被隐藏了,我们只是做了简单输出而以。但关键点是通过ProcessRequest()可以得到一个HttpContext对象的实例,并且明白这个单独的方法可以从开始到结束负责处理一个Web请求。
另外大家可能注意到了IHttpHandler接口支持一个名称为IsReusable的只读属性,用于指明是否可以安全的共享一个特定处理程序的实例。如果构建一个自定义处理程序,并且从此属性返回true,则在用处理程序的实例对请求提供服务时,Asp.net共享处理程序的实例。如果返回false,则每次服务请求时要创建处理程序的一个新实例。通常,处理程序共享与否并没有多大差别,因为CLR中的实例化机制和垃圾回收器是非常有效的,所以共享处理程序类并不会得到多大好处。需要考虑使用共享的一种情况是,需要耗费大量时间的处理程序,比如从数据库中进行检索。而Asp.net提供的标准处理程序从不使用处理程序共享。
上一篇:Asp.net大文件上传(一) | 下一篇:未完待续