[导入]研究大文件上传问题。
http://blog.joycode.com/saucer/archive/2004/03/16/16225.aspx
我们在上传大文件时都遇到过这样或那样的问题。设置很大的maxRequestLength值并不能完全解决问题,因为ASP.NET会block直到把整个文件载入内存后,再加以处理。实际上,如果文件很大的话,我们经常会见到Internet Explorer显示 "The page cannot be displayed - Cannot find server or DNS Error",好像是怎么也catch不了这个错误。为什么?因为这是个client side错误,server side端的Application_Error是处理不到的,可以参考这个帖子研究一下产生这个错误的机理。
handling server error when upload file too large
解决的方法是利用隐含的HttpWorkerRequest,用它的GetPreloadedEntityBody 和 ReadEntityBody方法从IIS为ASP.NET建立的pipe里分块读取数据
IServiceProvider provider = (IServiceProvider) HttpContext.Current;
HttpWorkerRequest wr = (HttpWorkerRequest) provider.GetService(typeof(HttpWorkerRequest));
byte[] bs = wr.GetPreloadedEntityBody();
....
if (!wr.IsEntireEntityBodyIsPreloaded())
{
int n = 1024;
byte[] bs2 = new byte[n];
while (wr.ReadEntityBody(bs2,n) >0)
{
.....
}
}
Chris Hynes为我们提供了这样的一个方案(用HttpModule),该方案除了允许你上传大文件外,还能实时显示上传进度:
这里有他讲座的PPT文件:
Uploading with ASP.NET (part 1)
Uploading with ASP.NET (part 2)
为这个问题已经找了好几天的资料了,可是都没有解决我的问题,上面的这篇文件被我找到了三次了,还是先收下来了再说。
根据讨论的结果来看,如果要解决大文件上传问题,我必须自己处理一些底层的请求处理了。
这里也有一篇文章:
http://weblogs.asp.net/cazzu/archive/2003/12/10/42635.aspx
Sometimes you need low level information about the current request in a web application, such as the IP address of the physical network adapter the request came through (cool in clustered multi-NIC servers), or some other weird stuff you can't find in the higher-level view provided by HttpRequest
, HttpResponse
and friends.
Luckily, the HttpContext
implements IServiceProvider
, which means you can ask for services with the following code:
IServiceProvider provider = (IServiceProvider) HttpContext.Current;
// Get the request
HttpRequest util = (HttpRequest)
provider.GetService(typeof(HttpRequest));
OK, I know... who on earth would use that instead of simply calling HttpContext.Current.Request
??? Well, THE one thing you can get that there's absolutely NO other way of getting, is the current HttpWorkerRequest
:
// Get the worker
HttpWorkerRequest wr = (HttpWorkerRequest)
provider.GetService(typeof(HttpWorkerRequest));
// Get the NIC address!!!!
string addr = wr.GetLocalAddress();
Another very cool use is to retrieve known header values. Usually, you just get the header from the Request.Header
collection by its name:
// Would return "Keep-Alive" if enabled.
string cn = Request.Headers["Connection"];
// Would return "gzip, deflate" for example.
string enc = Request.Headers["Accept-Encoding"];
but that's prone to errors, and you have to sort of guess the casing, etc. This is the cool way:
// Get the worker
HttpWorkerRequest wr = (HttpWorkerRequest)
provider.GetService(typeof(HttpWorkerRequest));
string cn = wr.GetKnownRequestHeader(HttpWorkerRequest.HeaderConnection);
string enc = wr.GetKnownRequestHeader(HttpWorkerRequest.HeaderAcceptEncoding);
Have a look at the class members , there are quite a few interesting things, now that you can call them ... and use them NOW, before they regret making such a beast available...
文章来源:http://computer.mblogger.cn/wucountry/posts/47779.aspx
/\_/\
(=^o^=) Wu.Country@侠缘
(~)@(~) 一辈子,用心做一件事!
--------------------------------
学而不思则罔,思而不学则怠!
================================
posted on 2005-10-12 18:18 Wu.Country@侠缘 阅读(2247) 评论(1) 编辑 收藏 举报