2014-02-14 31 views
16

我發現following great thread與如何使用新的HTML5 FORMDATA API如何在ASP.NET MVC中處理HTML5多文件上傳?

下面是代碼的小幅升級版本通過AJAX/jQuery的做文件上傳的解釋,與新的JQuery 1.8+語法

$(':button').click(function(){ 
    var formData = new FormData($('form')[0]); 
    $.ajax({ 
     url: '/Upload', //my ASP.NET MVC method 
     type: 'POST', 
     // handle the progress report 
     xhr: function() { // Custom XMLHttpRequest 
      var myXhr = $.ajaxSettings.xhr(); 
      if(myXhr.upload){ // Check if upload property exists 
       myXhr.upload.addEventListener('progress',progressHandlingFunction, false); // For handling the progress of the upload 
      } 
      return myXhr; 
     }, 

     // Form data 
     data: formData, 

     //Options to tell jQuery not to process data or worry about content-type. 
     cache: false, 
     contentType: false, 
     processData: false 
    }) 
    .done(function(){ 
     alert("success"); 
    }) 
    .fail(function(){ 
     alert("error"); 
    }); 
}); 

function progressHandlingFunction(e){ 
    if(e.lengthComputable){ 
     $('progress').attr({value:e.loaded,max:e.total}); 
    } 
} 

和這裏的形式

<form enctype="multipart/form-data"> 
    <input name="file" type="file" /> 
    <input type="button" value="Upload" /> 
</form> 
<progress></progress> 

在服務器端,我們有這樣的事情。

[HttpPost] 
public string Upload(HttpPostedFileBase file) 
{ 
    // do something with file 
    return "you uploaded a file called " + file.FileName; 
} 

這很好。直到您決定在文件對話框中使用「多個」屬性併發送多個文件。

<form enctype="multipart/form-data"> 
    <input name="file" type="file" multiple="multiple" /> 
    <input type="button" value="Upload" /> 
</form> 
<progress></progress> 

你會發現各種頁面在線提示如下解決方案

public string Upload(IEnumerable<HttpPostedFileBase> files) 
{ 
    foreach(var file in files) 
     ... 
} 

哎呀。不起作用

public string Upload(List<HttpPostedFileBase> files) 
{ 
    foreach(var file in files) 
     ... 
} 

沒有。不起作用。

public string Upload(IEnumerable files) 
{ 
    foreach(var file in files) 
     ... 
} 

甚至不編譯

public string Upload(HttpPostedFileBase[] files) 
{ 
    foreach(HttpPostedFileBase file in files) 
     ... 
} 

你猜怎麼着?不起作用。讓我們嘗試處理Request.Files。良好的舊可靠Request.Files。從未失敗。

public string Upload() 
{ 
    foreach (HttpPostedFileBase uf in Request.Files) 
     ... 
} 

擾流警報:它不起作用。

啊哈。得到它了!我將遍歷Request.Files中的鍵。

public string Upload() 
{ 
    foreach(var key in Request.Files.AllKeys) 
    { 
     var file = Request.Files[key]; 
    } 
} 

又一次,它不起作用。

回答

22

什麼確實工作,是下面的,總是可靠的from the blog和動態滿頭裏克施特拉爾

public string Upload() 
{ 
    for (int i = 0; i < Request.Files.Count; i++) 
    { 
     var file = Request.Files[i]; 
    } 
} 

這背後的原因是,文件傳遞給Request.Files集合所有具有相同的名稱,因爲它們來自單個文件上傳對話框。

服務器端方法傳遞包含文件對象,出於某種原因,Request.Files是得到它的唯一途徑。

希望我已經在添加該保存的人有點頭痛。

+0

怎麼樣的文件類型?我想讓用戶上傳類型爲「.jpg」,「.gif」,「.png」的文件......但由於所有文件都具有相同的名稱,我怎麼能得到任何文件的類型? – sohaiby

+1

您仍然可以訪問文件名,但包含這些文件的所有* post變量*都具有相同的名稱。將文件分配給'file'變量後,您可以檢查名稱和擴展名,並對其進行過濾。 – roryok

0

在我的情況有什麼對我來說是我的所有文件綁定到一個ViewModel領域工作。 ViewModel將成爲我用於我的前端的模型。

@using School.ViewModels 
@model UserProfileViewModel 


<form enctype="multipart/form-data"> 
<input id="username"name="username" type="text" /> 
<input name="Myfiles" type="file" multiple="multiple" /> 
<input type="button" value="Upload" /> 
</form> 

UserProfileViewModel.cs

namespace School.ViewModels 
{ 
    public class UserProfileViewModel 
    { 
     public long Username { get; set; } 

     public List<HttpPostedFileBase> Myfiles { get; set; } 
    } 
} 

UserProfilePicturesController.cs

public ActionResult Create([Bind(Include="Username,Myfilese")] UserprofileViewModel userprofileViewModel) 
{ 
    var files = userprofileViewModel.Myfiles; 
    foreach(HttpPostedFileBase file in files) 
    { 
     //do something here 
    } 
}