asp.net - 上载大文件

标签 asp.net webforms pagemethods web-farm

我是一名业余的ASP.net开发人员,正在从事我的第一份工作( friend 网站)。使用VS2010的ASP.net v4.0。

他的公司(使用3D打印机)制作3D模型。该网站目前正在开发中,但可以在here中找到。我将是第一个承认该代码有些仓促和被入侵的人,但是我的 friend 对他到目前为止所拥有的一切感到非常满意。

要求之一是他的客户需要能够上载他们的模型设计文件,每个文件设计文件最多可以100 MB(或更多)。我正在努力使它正常工作。

我从使用内置的<asp:FileUpload ID="FileUpload1" runat="server" />标记和动画gif图像开始,类似于Joe Stagner's tutorial中描述的想法-谢谢Joe,我非常喜欢您的演示文稿。

对于一个小的测试文件,这可以正常工作,但没有任何迹象表明上传进度。因此,我尝试使用Sunasara Imdadhusen在其code project article中提出的想法来改进我的解决方案。我的上传代码如下:

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);

其中stats是对类的引用,该类存储为 session 变量,并且可以通过PageMethod从在setInterval(...)中运行的javascript函数(正在上传)中访问:
[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;
    }
}

这在我的本地计算机上有效(使用线程sleep来减慢上传速度)。因此,我将其发布到我们的主机123-Reg中,但未按预期运行。上载开始时,动画gif会亮起,但进度栏不会开始移动。上传开始后应立即禁用的文件输入控件和“提交”按钮(在IFrame中)需要经过一段时间才能被禁用。然后,网页就卡在那里。等待一会后,我单击页面刷新按钮。页面刷新后,表明我的测试文件已成功上传。我尝试了16 KB文件和1.6 MB文件。

由于这在我的本地计算机上有效,因此我怀疑这是由于我们的网站托管服务器(123-Reg)使用的是Web服务器场。

无论如何,我认为这很容易,但事实并非如此,因此我寻找了一些开源上传进度条。我看过NeatUpload,但它说“默认情况下,NeatUpload在网络花园或网络农场中无法正常工作”,它还说要使其在网络农场中工作“请指定相同的随机32进制-每个服务器的Web.config部分中的digit解密密钥属性”。但是我认为我无法访问123-Reg的服务器配置文件(?)。

我的 friend 建议也许我们可以使用诸如保管箱之类的服务,但是我看了一下,也不知道如何将其添加到我们的网站。这可能是一个不错的选择,因为它们可能已针对上传进行了优化。

任何意见或建议将不胜感激-谢谢。

编辑:到目前为止的故事...仍在为此奋斗。

我详细研究了使用保管箱(以及其他云存储提供商,例如SkyDrive等)。似乎这些服务是围绕提供与单个用户的存储进行交互的应用程序而设计的。我希望所有用户都可以将文件上传到“我的保管箱”文件夹中,但不能共享(客户不应有权访问其他客户的设计文件)。无论如何,我继续进行操作,设置一个保管箱帐户,安装了Sharpbox SDK并重新编程了我的上传代码(任务动作中的位)。这在我的本地计算机上似乎可以正常工作,但速度稍慢,因为它正在上载到保管箱服务器(我不需要Thread.Sleep)。我将网站发布到123-Reg服务器,并获得了与以前类似的,无法使用的体验。

到目前为止,我一直在IE9上进行测试,而我恰好在Chrome上进行了试用,发现了一件有趣的事。在点击上传按钮之后,但在刷新页面之前,Chrome浏览器在左下方显示了%上传完成对话框。运行到100%,然后我的控件开始显示一些操作,然后整个页面开始再次挂起。

根据MSDN的HttpPostedFile:
“默认情况下,所有大于256 KB的请求(包括表单字段和上载的文件)都会缓存到磁盘上”

那么这是否意味着我的任务是在等待上载的痛苦部分之后开始的(实际上发生在客户端和缓冲区之间)?如果是这种情况,那么将文件发送到Dropbox使其更加痛苦就没有意义了吗?我的进度条正在跟踪错误的进度?

(今天,我将检查代码的错误处理,因为我感到它挂起的原因是因为它无法从异常中正确恢复)。确实感觉到我通过这样做中学到了很多东西。

最佳答案

这可能有点矫kill过正,但是您可以研究使用BluImp的jQuery File Upload工具(演示站点在此处:http://blueimp.github.com/jQuery-File-Upload/)-名为Max Pavlov的开发人员已修改了原始版本(最初是针对非dotnet技术的)以用于MVC 3。

可以在git hub https://github.com/maxpavlov/jQuery-File-Upload.MVC3上找到它。我已经在MVC 3和MVC 4 Beta中成功实现了这一点。为了使它在MVC 4中有效工作,我要做的唯一一件事就是删除一些ClientDependancy(这是一个用于处理JS和CSS文件的 bundle 和缩小的DLL)代码,因为这可以复制MVC 4中已有的功能,但不能复制MVC中的功能。 3.另外,我在GitHub上的Wiki上添加了一些页面,这些页面描述了我所做的尽管未完成。如果您决定沿这条路线走,我可以用我最近的发现更新一些细节。到目前为止,我在MVC 4集成方面的笔记可以在https://github.com/maxpavlov/jQuery-File-Upload.MVC3/wiki/MVC-4---EnableDefaultBundles中找到。

顺便说一句,我已经设法使用此工具上传了大约2Gb的文件,并且发现它非常灵活!

关于asp.net - 上载大文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11779751/

相关文章:

asp.net - 以声明方式访问转发器内的页面属性数据绑定(bind)

c# - 如何通过显示文本在 ASP.NET 下拉列表中设置所选项目?

c# - 从 javascript 调用 asp.net 页面方法不起作用

c# - 将类放在不同的文件夹中但在相同的 namespace 下调用它们?

c# - 我正在使用反射来获取 ASP.NET 中的属性名称和值需要一些优化建议

javascript - jquery 序列化和多选下拉列表

jquery - 在 PageMethod (asp.net) 中设置 session

c# - 在 asp.net 网站中为多个 session 用户交换内容

c# - 该程序集由比当前加载的运行时更新的运行时构建,无法加载

c# - AJAX 工具包模态弹出窗口不会出现