在大文件上传中,由于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",捕获不到这个错误
可以通过下面的方法解决:(分块读取上传文件)
首先自定义一个HttpModule ,实现IHttpModule接口,在Init中注册一个
application.BeginRequest += (new EventHandler(this.Application_BeginRequest));
protected void Application_BeginRequest(object sender, EventArgs e)
{
HttpApplication ha = sender as HttpApplication;
HttpContext context = ha.Context;
if (ha.Context.Request.ContentLength > 1000)//1000 is the max size
{
IServiceProvider provider = (IServiceProvider)context;
HttpWorkerRequest wr = (HttpWorkerRequest)provider.GetService(typeof(HttpWorkerRequest));
//FileStream fs = null;
// Check if body contains data
if (wr.HasEntityBody())
{
// get the total body length
int requestLength = wr.GetTotalEntityBodyLength();
// Get the initial bytes loaded
int initialBytes = 0; //wr.GetPreloadedEntityBody().Length;
if (!wr.IsEntireEntityBodyIsPreloaded())
{
byte[] buffer = new byte[100];
// Set the received bytes to initial bytes before start reading
int receivedBytes = initialBytes;
while (requestLength - receivedBytes >= initialBytes)
{
// Read another set of bytes
initialBytes = wr.ReadEntityBody(buffer, buffer.Length);
// Write the chunks to the physical file
// Update the received bytes
receivedBytes += initialBytes;
}
initialBytes = wr.ReadEntityBody(buffer, requestLength - receivedBytes);
}
}
//fs.Flush();
//fs.Close();
}
}
或者直接在Global.asax中的Application_BeginRequest Copy上面的代码
然后通过Page_Error或者Application_Error写提示信息
另外一个弊端就是当请求超过maxRequestLength(默认4M)之后,ASP.NET处理程序将不会处理该请求。这和ASP.NET抛出一个异常完全不同,这就是为什么如果用户上传文件太大,看到的并不是ASP.NET应用程序中指定的错误页面(或者默认的),因为ASP.NET还没有对这个请求进行处理。
还有一个问题就是处理ASP.NET大文件上传的超时。
这个其实可以通过在运行时读取web.config中的httpRuntime节,并转化为HttpRuntimeSection对象或者重写Page.OnError()来检测HTTP Code(相应代码)是否为400来处理,这里不再赘述,代码如下:
- System.Configuration.Configuration
- config = WebConfigurationManager.
- OpenWebConfiguration("~");
- HttpRuntimeSection section = config.GetSection
- ("system.web/httpRuntime") as HttpRuntimeSection;
- double maxFileSize = Math.Round
- (section.MaxRequestLength / 1024.0, 1);
- string errorString = string.Format("Make sure
- your file is under {0:0.#} MB.", maxFileSize);
- protected override void OnError(EventArgs e)
- {
- HttpContext ctx = HttpContext.Current;
- Exception exception = ctx.Server.GetLastError ();
- string errorString =
- "
Offending URL: " + ctx.Request.Url.ToString () +- "
Source: " + exception.Source +- "
Message: " + exception.Message +- "
Stack trace: " + exception.StackTrace;- ctx.Response.Write (errorString);
- ctx.Server.ClearError ();
- base.OnError (e);
- }
参考博客:http://www.xker.com/page/e2009/0722/73824.html
http://hi.baidu.com/xiaohaikong/blog/item/357ce8cec4d3a834f8dc6105.html
http://www.cftea.com/c/2009/02/QD9PQEACRTX76SLR.asp
http://msdn.microsoft.com/en-us/library/aa479319.aspx
http://www.cnblogs.com/lyj/archive/2008/10/30/1323099.html
http://www.cnblogs.com/legendxian/archive/2009/12/24/1631539.html
http://www.cnblogs.com/legendxian/archive/2009/12/29/1634953.html
http://blog.csdn.net/ylqndscylq/archive/2009/08/09/4427480.aspx
http://beniao.blog.51cto.com/389148/102304
http://www.360doc.com/content/06/0117/14/4821_59592.shtml