3

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

他的公司制作 3D 模型(使用 3D 打印机)。该网站目前正在开发中,但可以在这里找到。我会是第一个承认代码有点匆忙和被黑的人,但我的朋友对他到目前为止所拥有的非常满意。

其中一项要求是他的客户需要能够上传他们的模型设计文件,每个文件可能高达 100 MB(或更多)。我正在努力让它正常工作。

我开始使用内置<asp:FileUpload ID="FileUpload1" runat="server" />标签和动画 gif 图像,类似于Joe Stagner 教程中描述的想法- 谢谢 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);

wherestats是对存储为会话变量的类的引用,并且可以从setInterval(...)PageMethod 中运行的 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;
    }
}

这在我的本地机器上工作(使用线程睡眠来减慢上传速度)。所以我将它发布到我们的主机123-Reg并没有按预期工作。上传开始时动画 gif 出现,但进度条没有开始移动。文件输入控件和提交按钮(在 IFrame 中)应在上传开始后立即禁用,这需要很长时间才能禁用。然后网页就挂在那里。等了一会儿,我点击了页面刷新按钮。当页面刷新时,显示我的测试文件已成功上传。我尝试了一个 16 KB 的文件和一个 1.6 MB 的文件。

由于这在我的本地机器上运行,我怀疑这是因为我们的网站主机(123-Reg)正在使用网络农场。

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

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

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


编辑:到目前为止的故事......仍在为此苦苦挣扎。

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

到目前为止,我一直在 IE9 上进行测试,我只是碰巧用 Chrome 进行了尝试,我发现了一件有趣的事情。就在单击上传按钮之后但在页面刷新之前,Chrome 在左下角显示了一个上传完成百分比对话框。这跑到 100%,然后我的控件开始显示一些动作,然后整个页面再次开始挂起。

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

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

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

4

1 回答 1

1

这可能有点矫枉过正,但您可以考虑使用 BluImp 的 jQuery 文件上传工具(此处的演示站点: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 文件的捆绑和缩小的 DLL)代码,因为这复制了 MVC 4 中已经存在的功能,但在 MVC 中没有3. 此外,我在 GitHub 上的 wiki 上添加了一些页面,描述了我所做的事情,尽管它并不完整。如果你决定走这条路,我可以用我最近的发现更新一些细节。到目前为止,我关于 MVC 4 集成的笔记可以在这里找到https://github.com/maxpavlov/jQuery-File-Upload.MVC3/wiki/MVC-4---EnableDefaultBundles

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

于 2012-08-03T09:18:13.223 回答