2014-02-14 3 views
16

Я нашел following great thread с объяснением того, как сделать загрузку файлов через AJAX/Jquery с использованием нового HTML5 FormData APIКак обрабатывать несколько загрузок файлов HTML5 в ASP.NET MVC?

Вот немного обновленная версия этого кода, с новой 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; 
} 

Это прекрасно работает. Если вы решите использовать атрибут «multiple» в диалоговом окне файла и отправить несколько файлов.

<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) 
     ... 
} 

Nope. Не работает.

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) 
     ... 
} 

Спойлер предупреждает: он не работает.

Aha. Понял! Вместо этого я буду перебирать ключи в 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 variables *, содержащие эти файлы, имеют одинаковое имя. После того, как вы присвоили свой файл переменной '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 
    } 
} 
Смежные вопросы