2012-08-02 121 views
3

我是一名業餘ASP.net開發人員,負責我的第一份工作(朋友網站)。 ASP.net v4.0,使用VS2010。上傳大文件

他的公司生產3D模型(使用3D打印機)。該網站目前正在開發中,但可以找到here。我會第一個承認代碼有點匆匆入侵,但我的朋友對他到目前爲止很滿意。

其中一個要求是他的客戶需要能夠上傳他們的模型設計文件,每個文件可能高達100 MB(或者更多)。我努力讓這個工作正常。

我開始使用內置的<asp:FileUpload ID="FileUpload1" runat="server" />標籤和一個動畫gif圖像,類似於Joe Stagner's tutorial中描述的想法 - 感謝喬,我非常喜歡您的演示文稿。

這對一個小測試文件工作正常,但沒有給出任何上傳進度的跡象。所以我試圖用他的code project article中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); 

哪裏stats是存儲爲一個會話變量類的引用,並從一個JavaScript函數在setInterval(...)運行(而上傳正在發生)的訪問該PageMethod:

[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在網上花園或網上農場不能正常工作」,並且它也說讓它在Web場上工作「指定相同的隨機32-每個服務器的Web.config部分中的數字解密密鑰屬性「。但我不認爲我有權訪問123-Reg的服務器配置文件(?)。

我的朋友建議,也許我們可以使用服務,如dropbox,但我看了一下,我不知道如何將其添加到我們的網站。這可能是一個不錯的選擇,因爲它們可能針對上傳進行了優化。

任何意見或建議將非常感謝 - 謝謝。


編輯:到目前爲止的故事......仍然與此掙扎。

我仔細研究了使用Dropbox(以及其他雲存儲提供商,如SkyDrive等)。似乎這些服務是圍繞提供與個人用戶存儲交互的應用程序而設計的。我希望所有用戶能夠將文件上傳到我的Dropbox文件夾,但不共享(客戶不應訪問其他客戶的設計文件)。無論如何,我繼續,設置一個Dropbox帳戶,安裝Sharpbox SDK並重新編程我的上傳代碼(任務操作中的位)。這似乎在我的本地計算機上工作正常,但速度稍慢,因爲它正在上傳到保管箱服務器(我不需要Thread.Sleep)。我將網站發佈到123-Reg服務器,並得到了與以前類似的無法使用的體驗。

到目前爲止,我一直在IE9上進行測試,並且我只是想用Chrome瀏覽器進行測試,而且我注意到了一個有趣的事情。只需點擊上傳按鈕,但在刷新頁面之前,Chrome在左下角顯示一個上傳%完成對話框。這運行到100%,然後我的控件在整個頁面再次掛起之前開始顯示一些操作。

根據MSDN的HttpPostedFile: 「默認情況下,所有的請求,包括表單字段和上傳文件,大於256 KB的緩存到磁盤」

那麼,這是否意味着以後我的工作正在啓動等待上傳的痛苦部分(實際上發生在客戶端和緩衝區之間)?如果是這種情況,那麼通過將文件發送到Dropbox的方式使它更加痛苦是沒有意義的?我的進度條正在跟蹤錯誤的進度? (今天我要檢查我的代碼的錯誤處理,因爲我有一種感覺,它掛起的原因是因爲它沒有正確地從異常恢復)。這當然讓我感覺我正在學習很多東西。

+0

使用雲代替,如果它不貴,或者購買hostin自己的服務器。似乎託管提供商限制了請求大小。 – 2012-08-02 14:47:35

+0

根據[serialseb的帖子](http://stackoverflow.com/a/1156906/340045):只要您使用HttpRequest.InputStream,Asp.net就會始終加載整個請求內容,所以我想這可能會導致一些問題對我來說。 – Ben 2012-08-04 11:43:40

回答

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的文件,並發現它非常靈活!