作用

在上传数据时通过此模块可以查看上传进度。

原理

本模块可以分成两部分,一部分负责监测上传进度,另一部分负责显示。

监测上传进度

我参考了 http://www.codeproject.com/aspnet/File_Upload_Progress_Bar.asp 上面的方法,使用 HttpModule 拦截请求,然后代替底层的 HttpWorkerRequest 读取数据,读取的同时就可以进行计数。

与所参考的网页上的方法不同的是,我采用了异步处理,这样对资源的耗用就有望有所减轻 (虽然其实大部分时间都花在读取数据上,而且一读取完一段就立刻用 ThreadPool.QueueUserWorkItem() 安排下一次读取)。

另外,当发现一个可能需要监测上传进度的请求时,我的实现将会读取 Web.config 里所设定的最小请求长度和最大请求长度,且仅当预期请求长度在此范围内时才拦截。最小请求长度默认是 5 KB,设此限制可以避免无用的计数;最大请求长度默认是 8192 KB (在 Web.config 的 configuration / system.web / httpRuntime / @maxRequestLength 设置),设此限制可以避免客户端上传特大文件导致的拒绝服务攻击 (因为在 HttpApplication.BeginRequest 事件发生时,HttpRuntime 尚未对请求检查最大长度限制)。

再次,所参考网页上的方法生成过程中所需的 GUID,而我的实现是直接获取请求所用的 ASP.NET 会话 ID (Session ID) 作为保存计数器的键 (Key)。

显示上传进度

客户端可以打开任意位置的 UploadProgress.ashx 来查看当前上传进度。虽然这个文件看起来像是一个 HttpHandler,但其实不存在这个文件,也不需要在 Web.config 另行注册;UploadProgressModule 将会“拦截”对这个文件的请求,并且输出适当的响应内容。

输出的“页面”是个很特殊的 HTTP 响应流;它先输出完整的 HTML 来显示像这样的进度条:

30 KB / 100 KB ( 5 KB /s)

但是在 </html> 发送出去之后,仍然不关闭连接,而每两秒再发送一段 JavaScript 来更新进度条的显示。当然,一切都是用异步方法处理,以免占用过多资源。

该进度条页面有足够丰富的 JavaScript 用以处理一切异常,包括请求超时、连接被故意或无意中断等等情况,并在有需要的时候重新请求以显示最新的上传进度。

下载

 UploadProgressModule.zip (5.90 KB)

安装

下载后,将压缩包里所有 *.cs 文件放到 App_Code 下面,建议使用一个文件夹,例如 UploadProgress,单独存放它们。然后,参照 Web.config parts for UploadProgressModule.txt 的内容,在 Web.config 里添加 httpModules 节 (必需)。

再提醒:本模块只适用于 ASP.NET 2.0!

UploadProgressModule 可以通过 Web.config 里的 configuration / appSettings 节定制,所有项目均为可选,Web.config parts for UploadProgressModule.txt 的内容是这些设定的默认值。

UploadProgressGetterPath
从哪个路径可以打开查看上传进度的页面,默认为 "UploadProgress.ashx"。可以设为任何能被当前 ASP.NET 应用程序接收的路径,即使用 .aspx, .ascx, .ashx, .asmx, .config, .cs, .vb, .sitemap 等等扩展名的文件名。如果您的 IIS 将所有文件都映射给 ASP.NET ISAPI 则任意路径均可。UploadProgressModule 将拦截所有对用所设定的路径结尾的路径的请求,并输出上传进度。
UploadProgressChecksAllPostRequests
true 或 false,默认为 false。设为 true 则使 UploadProgressModule 监测所有 POST 请求的上传进度;设为 false 则仅监测可能有上传文件的 POST 请求 (Content-Type 为 "multipart/form-data")。
UploadProgressMinRequestLength
一个整数,代表使用 UploadProgressModule 监测上传进度的最小请求长度,以字节数 (bytes) 为单位,默认是 5120。UploadProgressModule 将不会监测请求长度小于此值或大于最大请求长度 (httpRuntime / @maxRequestLength, 注: 这个设定的单位是 KB) 的请求的上传进度。

使用示例

可以在上传按钮旁边增加一些代码,用来显示上传进度:

<script type="text/javascript">
function showUploadProgress() {
document.getElementById("UploadProgress").style.display = "";
frames["UploadProgressFrame"].location = "UploadProgress.ashx";
}
</script>
<asp:LinkButton ID="Upload" runat="server" Text="Upload"
OnClick="Upload_Click"
OnClientClick="setTimeout('showUploadProgress()', 1000)" />
<blockquote id="UploadProgress" style="display: none">
<iframe id="UploadProgressFrame" scrolling="no" frameborder="0"
width="300" height="25"></iframe>
</blockquote>

示范

由于本网站所用的空间提供的 .NET 安全权限不足,GetService() 方法调用失败,无法示范。

http://www.xuanmax.com/XuanCode/DotNet/UploadProgressModule.aspx

posted on 2007-02-12 13:55  mbskys  阅读(222)  评论(0)    收藏  举报