How to upload a file using ASP.NET MVC and AJAX

A very simple file uploader using the progress bar component from Bootstrap

I've decided to get my old upload post and upgrade the components I am using. For example: Before it was an MVC3 project made on Visual Studio 2010 using the old version of everything. Now it's a Visual Studio 2012 project, ASP.NET MVC4, using bootstrap and the newest version of each plugin I've used before.

First step

First of all we need to create a Model just like Scott Hanselman made in his article. Then we will have the name, length and type of our file:

public class UploadFilesResult
{
	public string Name { getset; }
	public int Length { getset; }
	public string Type { getset; }
}

Second step

We will need to create an Action Method which will take care of the upload. It will be called by using the http POST method, get the list of selected files and save into App_Data. This Action Method should return a json informing the name, length and type of the files:

[HttpPost]
public ContentResult UploadFiles()
{
	var r = new List<ViewDataUploadFilesResult>();
 
	foreach (string file in Request.Files)
	{
		HttpPostedFileBase hpf = Request.Files[file] as HttpPostedFileBase;
		if (hpf.ContentLength == 0)
			continue;
 
		string savedFileName = Path.Combine(Server.MapPath("~/App_Data"), Path.GetFileName(hpf.FileName));
		hpf.SaveAs(savedFileName); // Save the file
 
		r.Add(new ViewDataUploadFilesResult()
		{
			Name = hpf.FileName,
			Length = hpf.ContentLength,
			Type = hpf.ContentType
		});
	}
	// Returns json
	return Content("{\"name\":\"" + r[0].Name + "\",\"type\":\"" + r[0].Type + "\",\"size\":\"" + string.Format("{0} bytes", r[0].Length) + "\"}""application/json");
}

Third step

After that we only need to download a jQuery plugin called jQuery File Upload. It brings us lots of cool stuff but, for the sake of simplicity, we are gonna use only 2 files (apart from the others I am already using): jquery.fileupload.css and jquery.fileupload.js:

Fourth step

We need now a way to send these files. This is what I've created - just for the upload - but you can adapt into your page:

<div class="container">
	<span class="btn btn-success fileinput-button">
		<i class="glyphicon glyphicon-plus">i>
		<span>Add files...span>
		<input id="fileupload" type="file" name="files[]" multiple>
	span>
	<br />
	<div class="progress">
		<div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width0%;">
			<span class="sr-only">0% completespan>
		div>
	div>
	<br />
	<div class="file_name">div>
	<br />
	<div class="file_type">div>
	<br />
	<div class="file_size">div>
div>

Notice 4 things:

  1. I didn't use HtmlHelper to create the form. The reason is the ease to create the form without it. Also, we don't need to use HtmlHelpers all the time;
  2. I am not using a form tag. The plugin takes care of everything;
  3. The progress bar, thanks to bootstrap;
  4. The divs at the end, which will only receive the json data.

Last step

Now we need to make the javascript in order to make this work. I am using the jQuery File Upload plugin calling the Action Method UploadFiles created in the HomeController. In addition I have also attached an event which shows the upload status to the user by using the bootstrap progressbar component:

<script type="text/javascript">
	$(document).ready(function () {
		$('#fileupload').fileupload({
			dataType: 'json',
			url: '/Home/UploadFiles',
			autoUpload: true,
			done: function (e, data) {
				$('.file_name').html(data.result.name);
				$('.file_type').html(data.result.type);
				$('.file_size').html(data.result.size);
			}
		}).on('fileuploadprogressall'function (e, data) {
			var progress = parseInt(data.loaded / data.total * 100, 10);
			$('.progress .progress-bar').css('width', progress + '%');
		});
	});
script>

That's it. Now you are ready to add this feature to your website, without any postback.

Download the code here: jQueryFileUploadMVC4.zip (5.84 MB). Yes, almost 6MB thanks to the packages.