作用
在上传数据时通过此模块可以查看上传进度。
原理
本模块可以分成两部分,一部分负责监测上传进度,另一部分负责显示。
监测上传进度
我参考了 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
浙公网安备 33010602011771号