ASP.NET MVC AJAX File Upload

Uploading files using AJAX and ASP.NET MVC could not be simpler. And for the purests out there, this uses NO jQuery! This code actually allows the uploading of multiple files.

First, the client side. Half the work is done by the function buildFormData().

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>
<html>
	<head>
	<title></title>
	<script type="text/javascript">
	//used for posting "multipart/form-data"
	function buildFormData(form_object) {
		var fd = new FormData();
		for (var i = 0; i < form_object.elements.length; i++) {
			if (form_object.elements[i].name != null && form_object.elements[i].name != "") {
				if (form_object.elements[i].type == "checkbox") {
					if (form_object.elements[i].checked) {
						fd.append(form_object.elements[i].name, form_object.elements[i].value)
					}
				}
				else if (form_object.elements[i].type == "file") {
					for (var j = 0; j < form_object.elements[i].files.length; j++) {
						fd.append(form_object.elements[i].name,
						form_object.elements[i].files[j],
							form_object.elements[i].files[j].name)
					}
				}
				else {
					fd.append(form_object.elements[i].name, form_object.elements[i].value)
				}
			}
		}
		return fd;
	}
	function submitForm(oform)
	{
		if (window.FormData !== undefined) {
			document.getElementById("SubmitButton").disabled = true;
			var formData = buildFormData(oform);
			var xmlobj = createXMLHttp();
			xmlobj.onreadystatechange = function () {
				if (xmlobj.readyState == 4) {
					if (xmlobj.status == 200) {
						document.getElementById("divResponse").innerHTML = xmlobj.responseText;
						document.getElementById("SubmitButton").disabled = false;
					}
					else {
						throw new Error("Error: " + xmlobj.status + ": " + xmlobj.statusText);
					}
				}
			};
			xmlobj.open("post", oform.action, true);
			xmlobj.setRequestHeader("Content-Type", "multipart/form-data");
			xmlobj.send(formData);
		}
		else {
			alert("This browser does not support posting files with HTML5 and AJAX.");
		}
		return false;
	}
	</script>
	</head>
	<body>
	<form onsubmit="return submitForm(this);" method="post" action="/Ajax/UploadFile">
		<%: Html.AntiForgeryToken() %>
		<input type="text" required name="fullname" placeholder="enter your name here" /><br />
		<input type="file" accept="image/jpeg" multiple required name="file1" /><br />
		<input type="submit" id="SubmitButton" value="Upload File(s)" />
	</form>
	<div id="divResponse"></div>
	</body>
</html>

Next, the server side. Make a controller named "Ajax" and add the UploadFile() method.

// AjaxController.cs
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Mvc;
using System.Net;

namespace Website.Controllers
{
	public class AjaxController : Controller
	{
		[HttpPost]
		[ValidateInput(false)]
		[ValidateAntiForgeryToken]
		public string UploadFile()
		{
			Response.AddHeader("Pragma", "no-cache");
			Response.CacheControl = "no-cache";
			Response.Cache.SetAllowResponseInBrowserHistory(false);
			Response.Cache.SetCacheability(HttpCacheability.NoCache);
			Response.Cache.SetNoStore();
			Response.Expires = -1;

			int i;
			for (i = 0; i < Request.Files.Count; i++)
			{
				if (Request.Files[i].ContentLength > 0)
				{
					if (Request.Files[i].ContentType.ToLower() == "image/jpeg")
					{
						try
						{
							// make sure that this directory has write permissions
							Request.Files[i].SaveAs("C:\\UploadedImages\\" + Request.Files[i].FileName);
						}
						catch (Exception ex)
						{
							return ex.Message.ToString();
						}
					}
				}
			}
			return i.ToString() + " files copied. Hello, " + Request.Form["fullname"];
		}
	}
}

Finally, make sure that the server will accept large uploads and give the upload enough time to complete (timeout). Edit the Web.config file to have these sections.

<system.web>
	<httpRuntime executionTimeout="600" maxRequestLength="20480" requestValidationMode="2.0"/>
</system.web>
<system.webServer>
<security>
	<requestFiltering>
	<requestLimits maxAllowedContentLength="102400000"/>
	</requestFiltering>
</security>
</system.webServer>

It couldn't be any simpler!!!

See JPEG Library for help with resizing uploaded images.