Some time back I wrote a post explaining how to allow File Upload In An ASP.NET MVC Application. Here I am going to expand on the post a little an show how to allow multiple file upload in a single post to the server.
I used bootstrap for styling.
install-package bootstrap -projectname YourProjectName
The layout page is fairly bare, only style sheet links and a Renderbody html helper.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>File Upload Demo</title>
<link href="~/Content/bootstrap.min.css" rel="stylesheet" />
<link href="~/Content/bootstrap-theme.min.css" rel="stylesheet" />
<link href="~/Content/root.css" rel="stylesheet" />
</head>
<body>
<div>
@RenderBody()
</div>
</body>
</html>
The view model contains two list properties. A list of HttpPostedFileBase objects and a list of string.
namespace FileUpload.Models
{
public class MultipleFileUploadViewModel
{
public List<HttpPostedFileBase> UploadFilePaths { get; set; }
public List<string> Urls { get; set; }
}
}
When the view is posted to the server the list of posted files (HttpPostedFileBase) will be iterated in a for loop and the files saved to disk. The save locations will added to the model in the list of string.
namespace FileUpload.Controllers
{
public class HomeController : Controller
{
public ActionResult Multiple()
{
return View(new MultipleFileUploadViewModel());
}
[HttpPost]
public ActionResult Multiple(MultipleFileUploadViewModel model)
{
var selectedPaths = model.UploadFilePaths.Where(f => f != null);
if (selectedPaths.Count() == 0)
{
ModelState.AddModelError(string.Empty, "No files were selected for upload");
return View(model);
}
model.Urls = new List<string>();
foreach (var path in selectedPaths)
{
var fileName = Path.GetFileName(path.FileName);
var uploadPath = Path.Combine(Server.MapPath("~/uploads/"), fileName);
path.SaveAs(uploadPath);
model.Urls.Add(Url.Content(Path.Combine("/uploads/", fileName)));
}
return View(model);
}
}
}
The view has 4 file input boxes, they all have the same name which matches the name of the posted file list property. Also make sure the form has the multipart/form-data encryption, missing or wrong encryption will prevent the file data being posted to the controller.
@model FileUpload.Models.MultipleFileUploadViewModel
@{
ViewBag.Title = "Multiple File Upload";
}
<div class="container">
<h2>Index</h2>
<div class="clearfix">
@using (Html.BeginForm("multiple", "home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
@Html.AntiForgeryToken()
@Html.ValidationSummary()
<div class="panel panel-default">
<div class="panel-heading">
File Upload
</div>
<div class="panel-body">
<div class="form-group">
<span><strong>Files to upload</strong></span>
<div class="input-group">
<input type="file" name="UploadFilePaths" class="form-control" />
<input type="file" name="UploadFilePaths" class="form-control" />
<input type="file" name="UploadFilePaths" class="form-control" />
<input type="file" name="UploadFilePaths" class="form-control" />
</div>
<span>
<input type="submit" class="btn btn-default" value="Upload" />
</span>
</div>
</div>
</div>
}
@if (Model.Urls != null)
{
<ul>
@foreach (var url in Model.Urls)
{
<li><a href="@url" alt="" target="_blank">@url</a></li>
}
</ul>
}
</div>
</div>
One last thing to mention is file sizes. By default the largest upload size is 4MB. In this case with multiple files the total size of all files must not exceed the 4MB limit. Exceeding the limit will cause a Maximum Request Length Exceeded error. This maximum can be set in the web.config file as below.
<system.web>
<httpRuntime maxRequestLength="51200" executionTimeout="240" />
</system.web>
The maxRequestLength unit is kilobytes, so in this example 51200 = 50MB. The executionTimeout is set to 4 minutes (240 seconds).

You must be logged in to post a comment.