如何在ASP.NET MVC中处理HTML5多文件上传?

我找到了以下很棒的主题 ,并解释了如何使用新的HTML5 FormData API通过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}); } } 

这是表格

 

在服务器端,我们有类似的东西。

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

这很好用。 直到你决定在文件对话框中使用“multiple”属性,并发送多个文件。

 

您将在网上找到各种页面,建议以下解决方案

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

哎呀。 不起作用

 public string Upload(List 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]; } } 

然而,它不起作用。

从总是可靠和动态头发的Rick Strahl 的博客中可以得到以下工作

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

这背后的原因是传递给Request.Files的文件集合都具有相同的名称 ,因为它们来自单个文件上载对话框。

服务器端方法传递包含文件的单个对象,并且由于某种原因,Request.Files是获取它的唯一方法。

希望我通过添加这个来节省一些人的头痛。

在我的例子中,对我有用的是将我的所有文件绑定到ViewModel字段。 ViewModel将是我用于前端的模型。

 @using School.ViewModels @model UserProfileViewModel 

UserProfileViewModel.cs

 namespace School.ViewModels { public class UserProfileViewModel { public long Username { get; set; } public List 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 } }