ASP.NET本质论
上QQ阅读APP看书,第一时间看更新

1.3.3 默默无闻的工作者对象

在ASP.NET中,准备用于处理的请求,必须封装为HttpWorkerRequest类型的对象,这是一个抽象类,定义在System.Web命名空间中,类型定义如下:

[ComVisibleAttribute(false)]
public abstract class HttpWorkerRequest

通过这个类的对象实例,必须提供关于处理请求所需要的信息,以便于服务器处理请求。HttpWorkerRequest中的成员见表1-2和表1-3。

表1-2 HttpWorkerRequest中关于请求部分的成员

表1-3 HttpWorkerRequest中关于回应部分的成员

HttpWorkerRequest是一个很底层的类,主要用于ASP.NET服务器内部使用,在一些特殊的情况下,它可以帮助我们完成一些特殊的任务,比如,在上传文件的时候,默认情况下,ASP.NET会将上传文件的内容读取到服务器的内存中,然后通过控件的形式提供给程序员使用,这种机制在上传比较小的文件时非常方便,但是,当上传很大的文件时,服务器的内存将会出现问题,导致浏览器不能将文件继续传输,浏览器将显示:"The page cannot be displayed -Cannot find server or DNS Error"。这个错误无法在服务器端进行捕捉和处理。

借助于HttpWorkerRequest的GetPreloadedEntityBody和ReadEntityBody方法,我们可以自己分块从客户端读取上传的文件内容,然后,将内容保存在一个临时文件中。有许多基于这个机制的实现,其中,Chris Hynes写了一个基于HttpWorkerRequest的上传组件SlickUpload,这个组件的地址是http://krystalware.com/Products/SlickUpload/。另外,博客园的“WuCountry@侠缘”针对大文件上传问题提供了一个开源、免费的版本,地址是http://www.cnblogs.com/WuCountry/archive/2005/12/28/306725.html在实际开发中,我们需要创建它的派生类,在System.Web.Hosting命名空间中,已经定义了一个派生类SimpleWorkerRequest,简单情况下,我们可以直接使用这个类,或者从这个类进行派生。其定义如下:

[ComVisibleAttribute(false)]
public class SimpleWorkerRequest :HttpWorkerRequest

这个类提供了两个简单的构造函数,其中比较简单的一个如下:

public SimpleWorkerRequest(
    string page,
    string query,
    TextWriter output
)

其中,page为一个.aspx的页面的名称,query为请求参数,output为内容的输出流。

SimpleWorkerRequest可以处理简单的请求参数,然后,将返回的主体内容输出到一个TextWriter流中。如果需要处理上传文件的请求,或者需要输出二进制的输出,那么应该扩展这个类,或者自定义一个HttpWorkerRequest的派生类来实现更加丰富的功能。