In this article I will demonstrate how to upload single or multiple files using HttpPostedFileBase in MVC with some validations.
Most of the time I heard developers saying they are not able to find the file they want to upload in their MVC application. File uploading in MVC is very simple but on the same side it is little tricky. In this article I will try to explain, how can we upload single or multi files in MVC. I will use HttpPostedFileBase class to get my files in controller. This class is the base class to provide For more details on HttpPostedFileBase you can click here.
You should change form encoding type to multipart/form-data to enable file uploading. Your file is automatically available in Request parameter or you can find it in HttpPostedFileBase class also.
Let's start step by step. I will show example for both single and multiple files upload. Let's do with single file
I am starting from controller. Below is the code for single file upload.
public ActionResult Upload(HttpPostedFileBase fileUpload)
{
if (fileUpload != null)
{
string folderPath = Server.MapPath("~/Upload/");
fileUpload.SaveAs(folderPath + "," + fileUpload.FileName);
}
return View("Index");
}
To upload multiple files everything will be same except one thing. I am taking a list of HttpPostedFileBase class. Below is the code to upload multi files.
public ActionResult UploadMulti(IEnumerable<HttpPostedFileBase> fileUploadMulti)
{
foreach (HttpPostedFileBase fileUpload in fileUploadMulti)
{
if (fileUpload != null)
{
string folderPath = Server.MapPath("~/Upload/");
fileUpload.SaveAs(folderPath + "," + fileUpload.FileName);
}
}
return View("Index");
}
You can also upload multiple files at a time selecting all in one file upload control. For this you need to use multiple='multiple' attribute from HTML5. Rest code will be same as of multiple file upload. You will use IEnumerable<HttpPostedFileBase> object and will get all selected file in one go.
<input type="file" id="fileUploadMultiUsingOneControl" name="fileUploadMultiUsingOneControl" multiple="multiple" />
Now let's see full code.
Let me add these code in one file. I am taking my class name as ExampleController.cs as I do generally. Adding additional reference for dll System.IO to play with directories.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.IO;
namespace DotNetConceptSampleFileUploadExample.Controllers
{
public class ExampleController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Upload(HttpPostedFileBase fileUpload)
{
if (fileUpload != null)
{
string folderPath = Server.MapPath("~/Upload/");
if (!Directory.Exists(folderPath))
{
Directory.CreateDirectory(folderPath);
}
fileUpload.SaveAs(folderPath + "," + fileUpload.FileName);
ViewData["UploadMessage"] = "File Uploaded successfully";
}
else
{
ViewData["UploadMessage"] = "File not uploaded. Please check your file.";
}
return View("Index");
}
public ActionResult UploadMulti(IEnumerable<HttpPostedFileBase> fileUploadMulti)
{
int i = 0;
foreach (HttpPostedFileBase fileUpload in fileUploadMulti)
{
if (fileUpload != null)
{
string folderPath = Server.MapPath("~/Upload/");
if (!Directory.Exists(folderPath))
{
Directory.CreateDirectory(folderPath);
}
fileUpload.SaveAs(folderPath + "," + fileUpload.FileName);
ViewData["UploadMultiMessage"] = "File Uploaded successfully.";
i++;
}
}
ViewData["UploadMultiMessage"] = i + " File(s) uploaded successfully.";
return View("Index");
}
}
}
After controller now it's time to add my HTML. I created two sections in my Index.cshtml page, one for single file upload and other for multi. You can use any of these as per your requirement. Below is the code for my view.
<h4>File Upload Example-Single</h4>
<div class="section">
@{using (Html.BeginForm("Upload", "Example", FormMethod.Post, new { @enctype = "multipart/form-data" }))
{
<div class="line">
<div class="line-heading">Attachment</div>
<div class="line-input"><input type="file" id="fileUpload" name="fileUpload" onchange="ValidateUpload(this)" /> </div>
</div>
<div class="line">
<input type="submit" id="btnUpload" value="Upload" onclick="return IsValid_Single();"/>
<span>@ViewData["UploadMessage"]</span>
</div>
}
}
</div>
<div style="clear:both;"> </div>
<h4>File Upload Example-Multi</h4>
<div class="section">
@{using (Html.BeginForm("UploadMulti", "Example", FormMethod.Post, new { @enctype = "multipart/form-data" }))
{
<div class="line">
<div class="line-heading">Attachment 1</div>
<div class="line-input"><input type="file" id="fileUploadMulti_0" name="fileUploadMulti" onchange="ValidateUpload(this)" /> </div>
</div>
<div class="line">
<div class="line-heading">Attachment 2</div>
<div class="line-input"><input type="file" id="fileUploadMulti_1" name="fileUploadMulti" onchange="ValidateUpload(this)" /> </div>
</div>
<div class="line">
<div class="line-heading">Attachment 3</div>
<div class="line-input"><input type="file" id="fileUploadMulti_2" name="fileUploadMulti" onchange="ValidateUpload(this)" /> </div>
</div>
<div class="line">
<input type="submit" id="btnUploadMulti" value="Upload" onclick="return IsValid_Multi();" />
<span>@ViewData["UploadMultiMessage"]</span>
</div>
}
}
</div>
Now I am almost done. Just I am putting some validation code. In this example I am restricting user to save only PNG images.
For png image format I am using image/png type. You can other type also for different formats you need.
Below is the javascript validation code I am using in my example.
<script type="text/javascript">
function IsValid_Single()
{
var fileCount = fileUpload.files.length;
if (fileCount > 0)
{
return ValidateUpload(fileUpload);
}
alert("Please select a file to upload.");
return false;
}
function IsValid_Multi() {
return Validate();
}
function Validate() {
var hasfile = false;
for (var i = 0; i < 3; i++)
{
var file = document.getElementById("fileUploadMulti_" + i).files[0];
if (file != null) {
hasfile = true;
name = file.name;
size = file.size;
type = file.type;
if (type != "image/png" || size > 10240) {
alert("Please select a png file below 10Kb in size.");
return false;
}
}
}
if (!hasfile)
{
alert("Please select a file to upload.");
return false;
}
return true;
}
function ValidateUpload(file) {
var file = file.files[0];
name = file.name;
size = file.size;
type = file.type;
if (type != "image/png" || size > 10240) {
alert("Please select a png file below 10Kb in size.");
return false;
}
return true;
}
</script>
That's it. I am done. You can download the code from top. You can also do same thing creating your own model keeping return type as HttpPostedFileBase or you can get files details in Request parameter also. Rest step will be same. Hope it can help you. So try yourself and use in your application.