2009-06-20 106 views
6

我需要客戶端(最終用戶)通過瀏覽器上傳大文件(例如類似於上傳大視頻文件的Youtube場景),文件大小不應超過500M字節。文件上傳問題

我使用ASP.Net + C#+ VSTS + IIS 7.0作爲我的開發平臺。有關如何處理大文件上傳問題的任何想法或良好實踐?任何參考樣本或文件的讚賞。

回答

2

this related question的回覆建議SWFUploadNeatUpload用於通過瀏覽器上傳大文件。 NeatUpload是一個ASP.NET組件,可能很適合你的環境。

還有JUpload

+0

感謝科林,還有一個問題,爲什麼使用基於RIA的解決方案是首選,因爲更好的上傳性能或其他? – George2 2009-06-20 09:25:34

+1

對標準HTTP的瀏覽器支持不允許指定允許哪些文件類型的東西,還有像flash/java更好支持進度條的東西 – 2009-06-20 09:42:27

+0

1.使用FileUpload控件無法指定文件類型?我很困惑。 2.我認爲使用非基於RIA的解決方案也可以實施進度條,例如我們如何上傳附件是Gmail。所以,這並不意味着使用普通的Http無法實現進度條。任何意見? – George2 2009-06-20 10:35:15

2

您需要設置的maxRequestLength適當地處理大文件,還可以設置executionTimeout使IIS不會放棄請求,在web.config文件

<system.web> 
    <httpRuntime executionTimeout="300" maxRequestLength="512000" /> 
</system.web> 

更多detailes是here喬恩Gallowy關於上傳大文件的文章。

下面是文章MSDN約在asp.net上傳文件2.0

1

幾乎所有的網站,處理非常大的上傳通過使用Adobe Flash默認這樣做。通常他們會回到簡單的瀏覽器上傳,但管理當前上傳的進度在Flash中更容易實現。

6
<system.web> 
     <httpRuntime executionTimeout="300" maxRequestLength="512000" /> 
    </system.web> 

這不會在IIS7中工作! httpRuntime用於IIS6和波紋管。正確的方法,以允許在IIS7大文件上傳是:

1)以下行添加到web.config文件:

[Web.config中] maxAllowedContentLength爲IIS7

屬性
<system.webServer> 
    <security > 
     <requestFiltering> 
      <requestLimits maxAllowedContentLength="1024000000" /> 
     </requestFiltering> 
    </security> 
</system.webServer> 

2 )然後打開文件C:\ WINDOWS \ SYSTEM32 \ INETSRV \設置\的applicationHost.config並找到行:

<section name="requestFiltering" overrideModeDefault="Allow" /> 

overrideModeDefault應該被允許。

0

我有這個問題,發現基於Jonathan's code here的解決方案。他的代碼存在一些問題,但這是我的解決方案。如果你想上傳一個大文件,比如1Gbyte文件,你必須查找文件並通過多個請求發送(一個請求會超時)。首先設置客戶端和服務器端的最大限制。

<system.webServer> 
<security> 
    <requestFiltering> 
    <requestLimits maxAllowedContentLength="2147483647" /> 
    </requestFiltering> 
</security> 
<system.webServer> 

<system.web> 
    <httpRuntime targetFramework="4.5" maxRequestLength="2147483647" /> 
</system.web> 

那麼大塊的文件,併發送每個吸盤,等待響應,併發送下一個數據塊。這裏是JavaScript和控制器代碼。

<div id="VideoDiv"> 
     <label>Filename:</label> 
     <input type="file" id="fileInput" /><br/><br/> 
     <input type="button" id="btnUpload" value="Upload a presentation"/><br/><br/> 
     <div id="progressbar_container" style="width: 100%; height: 30px; position: relative; background-color: grey; display: none"> 
      <div id="progressbar" style="width: 0%; height: 100%; position: absolute; background-color: green"></div> 
      <span id="progressbar_label" style="position: absolute; left: 35%; top: 20%">Uploading...</span> 
     </div> 
    </div> 

Javascript代碼夾頭,呼叫控制器和更新進度:

 var progressBarStart = function() { 
      $("#progressbar_container").show(); 
     } 

     var progressBarUpdate = function (percentage) { 
      $('#progressbar_label').html(percentage + "%"); 
      $("#progressbar").width(percentage + "%"); 
     } 

     var progressBarComplete = function() { 
      $("#progressbar_container").fadeOut(500); 
     } 

     var file; 

     $('#fileInput').change(function(e) { 
      file = e.target.files[0]; 
     }); 

     var uploadCompleted = function() { 
      var formData = new FormData(); 
      formData.append('fileName', file.name); 
      formData.append('completed', true); 

      var xhr2 = new XMLHttpRequest(); 
      xhr2.onload = function() { 
       progressBarUpdate(100); 
       progressBarComplete(); 
      } 
      xhr2.open("POST", "/Upload/UploadComplete?fileName=" + file.name + "&complete=" + 1, true); 
      xhr2.send(formData); 
     } 

     var multiUpload = function(count, counter, blob, completed, start, end, bytesPerChunk) { 
      counter = counter + 1; 
      if (counter <= count) { 
       var chunk = blob.slice(start, end); 
       var xhr = new XMLHttpRequest(); 
       xhr.onload = function() { 
        start = end; 
        end = start + bytesPerChunk; 
        if (count == counter) { 
         uploadCompleted(); 
        } else { 
         var percentage = (counter/count) * 100; 
         progressBarUpdate(percentage); 
         multiUpload(count, counter, blob, completed, start, end, bytesPerChunk); 
        } 
       } 
       xhr.open("POST", "/Upload/MultiUpload?id=" + counter.toString() + "&fileName=" + file.name, true); 
       xhr.send(chunk); 
      } 
     } 

     $("#VideoDiv").on("click", "#btnUpload", function() { 
      var blob = file; 
      var bytesPerChunk = 3757000; 
      var size = blob.size; 

      var start = 0; 
      var end = bytesPerChunk; 
      var completed = 0; 
      var count = size % bytesPerChunk == 0 ? size/bytesPerChunk : Math.floor(size/bytesPerChunk) + 1; 
      var counter = 0; 
      progressBarStart(); 
      multiUpload(count, counter, blob, completed, start, end, bytesPerChunk); 
     }); 

,這裏是上傳控制器存儲在chucnk(「App_Data文件/影片/溫度」),後來合併它們和存儲在(「App_Data文件/視頻」):

public class UploadController : Controller 
{ 
    private string videoAddress = "~/App_Data/Videos"; 

    [HttpPost] 
    public string MultiUpload(string id, string fileName) 
    { 
     var chunkNumber = id; 
     var chunks = Request.InputStream; 
     string path = Server.MapPath(videoAddress+"/Temp"); 
     string newpath = Path.Combine(path, fileName+chunkNumber); 
     using (FileStream fs = System.IO.File.Create(newpath)) 
     { 
      byte[] bytes = new byte[3757000]; 
      int bytesRead; 
      while ((bytesRead=Request.InputStream.Read(bytes,0,bytes.Length))>0) 
      { 
       fs.Write(bytes,0,bytesRead); 
      } 
     } 
     return "done"; 
    } 

    [HttpPost] 
    public string UploadComplete(string fileName, string complete) 
    { 
     string tempPath = Server.MapPath(videoAddress + "/Temp"); 
     string videoPath = Server.MapPath(videoAddress); 
     string newPath = Path.Combine(tempPath, fileName); 
     if (complete=="1") 
     { 
      string[] filePaths = Directory.GetFiles(tempPath).Where(p=>p.Contains(fileName)).OrderBy(p => Int32.Parse(p.Replace(fileName, "$").Split('$')[1])).ToArray(); 
      foreach (string filePath in filePaths) 
      { 
       MergeFiles(newPath, filePath); 
      } 
     } 
     System.IO.File.Move(Path.Combine(tempPath, fileName),Path.Combine(videoPath,fileName)); 
     return "success"; 
    } 

    private static void MergeFiles(string file1, string file2) 
    { 
     FileStream fs1 = null; 
     FileStream fs2 = null; 
     try 
     { 
      fs1 = System.IO.File.Open(file1, FileMode.Append); 
      fs2 = System.IO.File.Open(file2, FileMode.Open); 
      byte[] fs2Content = new byte[fs2.Length]; 
      fs2.Read(fs2Content, 0, (int) fs2.Length); 
      fs1.Write(fs2Content, 0, (int) fs2.Length); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex.Message + " : " + ex.StackTrace); 
     } 
     finally 
     { 
      if (fs1 != null) fs1.Close(); 
      if (fs2 != null) fs2.Close(); 
      System.IO.File.Delete(file2); 
     } 
    } 
} 

但是,如果兩個用戶具有相同名稱的同一時間上傳文件,會出現一些問題,你必須處理這個問題。通過閱讀responseText,你可以捕捉到一些錯誤和異常,並修剪它。