Asp.net 上传大文件
我是一名业余ASP.net开发人员,正在从事我的第一份工作(朋友网站)。ASP.net v4.0,使用VS2010 他的公司制作3D模型(使用3D打印机)。该网站目前正在开发中,但可以找到。我会第一个承认代码有点仓促和被黑客入侵,但我的朋友对他目前所做的感到非常高兴 其中一个要求是,他的客户需要能够上传他们的模型设计文件,每个文件的大小可能高达100MB(或者更多)。我正在努力让它正常工作 我开始使用内置的Asp.net 上传大文件,asp.net,webforms,pagemethods,web-farm,Asp.net,Webforms,Pagemethods,Web Farm,我是一名业余ASP.net开发人员,正在从事我的第一份工作(朋友网站)。ASP.net v4.0,使用VS2010 他的公司制作3D模型(使用3D打印机)。该网站目前正在开发中,但可以找到。我会第一个承认代码有点仓促和被黑客入侵,但我的朋友对他目前所做的感到非常高兴 其中一个要求是,他的客户需要能够上传他们的模型设计文件,每个文件的大小可能高达100MB(或者更多)。我正在努力让它正常工作 我开始使用内置的-谢谢Joe,我非常喜欢你的演示文稿 这对于一个小的测试文件来说是可行的,但是没有给出上传
-谢谢Joe,我非常喜欢你的演示文稿
这对于一个小的测试文件来说是可行的,但是没有给出上传进度的任何指示。因此,我试图利用Sunasara Imdadhusen在其著作中提出的想法来改进我的解决方案。我的上传代码如下所示:
Task t = Task.Factory.StartNew(() =>
{
byte[] buffer = new byte[UPLOAD_BUFFER_BYTE_SIZE];
// Upload the file in chunks so that we can measure how long it is taking.
using (FileStream fs = new FileStream(Path.Combine(newQuotePath, filename), FileMode.Create))
{
DateTime stopwatch = DateTime.Now;
while (stats.Uploaded < stats.TotalSize)
{
int bytecount = postedFile.InputStream.Read(buffer, 0, UPLOAD_BUFFER_BYTE_SIZE);
fs.Write(buffer, 0, bytecount);
stats.Uploaded += bytecount;
double dRate = UPLOAD_BUFFER_BYTE_SIZE / Math.Abs((DateTime.Now - stopwatch).TotalSeconds);
stats.Rate = (int)(Math.Min(dRate, int.MaxValue));
// Sleep is for debugging only!
//System.Threading.Thread.Sleep(2000);
stopwatch = DateTime.Now;
}
}
}, TaskCreationOptions.LongRunning);
这在我的本地机器上起作用(使用线程睡眠来减慢上传速度)。所以我把它发布给了我们的主持人,但它没有按预期工作。上传开始时,动画gif会显示,但进度条不会开始移动。文件输入控件和提交按钮(在IFrame中)应该在上传开始后立即禁用,但需要很长时间才能禁用。然后网页就挂在那里了。等了一会儿,我点击了页面刷新按钮。当页面刷新时,显示我的测试文件已成功上载。我尝试了一个16 KB的文件和一个1.6 MB的文件
由于这在我的本地机器上工作,我怀疑这是因为我们的网站主机(123 Reg)正在使用一个web服务器场
无论如何,我认为这会很容易,但事实并非如此,所以我寻找了一些开源上传进度条。我看了一下,但它说“默认情况下,NeatUpload在web garden或web farm上无法正常工作”,它还说,要让它在web farm上工作,“请在每个服务器的web.config部分指定相同的随机32位十六进制数字解密密钥属性”。但我不认为我有权访问123 Reg的服务器配置文件(?)
我的朋友建议我们可以使用dropbox这样的服务,但我看了一下,不知道如何将其添加到我们的网站上。这可能是一个很好的选择,因为它们可能针对上传进行了优化
如果您有任何建议,我们将不胜感激-谢谢
编辑:到目前为止的故事。。。仍在为此挣扎
我详细研究了dropbox的使用(以及SkyDrive等其他云存储提供商)。这些服务似乎是围绕提供与单个用户的存储交互的应用程序而设计的。我希望所有用户都能够上传文件到我的dropbox文件夹,但不需要共享(客户不应该访问其他客户的设计文件)。无论如何,我继续,设置了一个dropbox帐户,安装了并重新编程了我的上传代码(任务操作中的位)。这在我的本地机器上似乎可以正常工作,但速度稍慢,因为它正在上传到dropbox服务器(我不需要Thread.Sleep)。我将网站发布到123注册服务器,获得了与以前类似的、无法使用的体验
到目前为止,我一直在IE9上测试,我只是碰巧用Chrome试用了一下,我注意到了一件有趣的事情。点击上传按钮后,页面刷新前,Chrome在左下角显示上传完成百分比对话框。这达到了100%,然后在整个页面再次挂起之前,我的控件开始显示一些操作
根据MSDN:
默认情况下,所有大于256 KB的请求(包括表单字段和上载的文件)都会缓冲到磁盘
那么,这是否意味着我的任务是在等待上传的痛苦部分之后开始的(这实际上发生在客户端和缓冲区之间)?如果是这样的话,那么将文件发送到dropbox使其更加痛苦是没有意义的,对吗?而我的进度条正在跟踪错误位的进度
(今天我将检查代码的错误处理,因为我感觉它挂起的原因是它没有正确地从异常中恢复)。这当然让我觉得我从中学到了很多东西。这可能有点过头了,但你可以研究一下使用BluImp的jQuery文件上传工具(这里是演示站点:)-一位名为Max Pavlov的开发人员修改了原始版本(最初用于非点网技术),以便在MVC 3中使用
可以在git hub上找到它。我已经在MVC 3和MVC 4测试版中成功地实现了这一点。要使它在MVC4中有效工作,我唯一要做的就是删除一些clientdependency(这是一个处理JS和CSS文件绑定和缩小的DLL)代码,因为这复制了MVC4中已有的功能,而不是MVC3中的功能。此外,我还在GitHub上的wiki中添加了一些页面,描述了我所做的事情,尽管还不完整。如果你决定走这条路,我可以用我最近的发现更新那里的一些细节。到目前为止,我关于MVC4集成的笔记可以在这里找到
顺便说一句,我已经设法上传文件高达约2Gb使用这个工具,并发现它相当灵活 如果云对您来说不贵的话,可以使用云,或者为hostin购买自己的服务器。似乎主机提供商限制了请求大小。根据:Asp.net总是在使用HttpRequest.InputStream时加载整个请求内容,所以我想这可能会给我带来一些问题。
[System.Web.Services.WebMethod]
[System.Web.Script.Services.ScriptMethod]
public static UploadStatus GetFileUploadStatus()
{
UploadStatus stats = (UploadStatus)HttpContext.Current.Session["UploadFileStatus"];
if ((stats != null) && (stats.IsReady))
{
return stats;
}
else
{
return null;
}
}