Asp.net大文件上传解决方案

在大文件上传中,由于IIS对内存的保护机制,使得HttpWorkerRequest还没有转换成Request就由于内存占用太大而被终止了,所以我们在要可以获得HttpWorkRequest的时候将这里面的数据写到磁盘上,这样就不会使内存超出范围了。

在用FileUpload上传控件上传文件时,通过Web.Config文件的httpRuntime节设置maxRequestLength属性来解决它默认上传容量为4M就报错的问题,但他没有抛出异常,那是因为他还没有处理这个请求。通过读取配置文件,比照预读的上传文件大小,直接抛出异常,ASP.NET还没有处理到这个请求。

通过更改maxRequestLength的最大值,并不能解决文件上传容量超过限制值,报错但没有抛出异常的问题,

Internet Explorer显示 "The page cannot be displayed - Cannot find server or DNS Error",捕获不到这个错误

可以通过下面的方法解决:(分块读取上传文件)

 1 application.BeginRequest += (new EventHandler(this.Application_BeginRequest));
 2 
 3 protected void Application_BeginRequest(object sender, EventArgs e)
 4 {
 5     HttpApplication ha = sender as HttpApplication;
 6     HttpContext context = ha.Context;
 7 
 8     if (ha.Context.Request.ContentLength > 1000)//1000 is the max size
 9     {
10         IServiceProvider provider = (IServiceProvider)context;
11         HttpWorkerRequest wr = (HttpWorkerRequest)provider.GetService(typeof(HttpWorkerRequest));
12         //FileStream fs = null;
13         // Check if body contains data
14         if (wr.HasEntityBody())
15         {
16             // get the total body length
17             int requestLength = wr.GetTotalEntityBodyLength();
18             // Get the initial bytes loaded
19             int initialBytes = 0; //wr.GetPreloadedEntityBody().Length;
20 
21             if (!wr.IsEntireEntityBodyIsPreloaded())
22             {
23                 byte[] buffer = new byte[100];
24                 // Set the received bytes to initial bytes before start reading
25                 int receivedBytes = initialBytes;
26                 while (requestLength - receivedBytes >= initialBytes)
27                 {
28                     // Read another set of bytes
29                     initialBytes = wr.ReadEntityBody(buffer, buffer.Length);
30                     // Write the chunks to the physical file
31 
32                     // Update the received bytes
33                     receivedBytes += initialBytes;
34                 }
35                 initialBytes = wr.ReadEntityBody(buffer, requestLength - receivedBytes);
36 
37             }
38         }
39         //fs.Flush();
40         //fs.Close();
41     }
42 }



首先自定义一个HttpModule ,实现IHttpModule接口,在Init中注册一个

或者直接在Global.asax中的Application_BeginRequest Copy上面的代码

然后通过Page_Error或者Application_Error写提示信息

posted @ 2013-02-28 12:17  wsion  阅读(313)  评论(0编辑  收藏  举报