BY AJEESH M S COMMENTS

Upload files using AJAX in ASP.Net MVC

In one of my recent projects, I had a requirement to uploads files with AJAX. There are several jQuery plugins available, but I really don’t wanna use any of them. After little research, I found a solution. It is very simple and can do it even without jQuery. The HTML Markup

First, setup a simple form with a fileinput and submit button.

<form id="uploader">
    <input id="fileInput" type="file" multiple>
    <input type="submit" value="Upload file" />
</form>

Method 1 - Using JavaScript’s FormData object

The best method recommended if you don’t target legacy browsers and IE9. We will be sending data to server using JavaScript’s new FormData object. This object is new in XMLHttpRequest Level 2 and not supported in all browsers. FormData object represent form fields and values as key/value pairs. Just append files to FormData object and send with XMLHttpRequest. Here goes our script.

The JavaScript

window.onload = function () {
    document.getElementById('uploader').onsubmit = function () {
        var formdata = new FormData(); //FormData object
        var fileInput = document.getElementById('fileInput');
        //Iterating through each files selected in fileInput
        for (i = 0; i < fileInput.files.length; i++) {
            //Appending each file to FormData object
            formdata.append(fileInput.files[i].name, fileInput.files[i]);
        }
        //Creating an XMLHttpRequest and sending
        var xhr = new XMLHttpRequest();
        xhr.open('POST', '/Home/Upload');
        xhr.send(formdata);
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4 && xhr.status == 200) {
                alert(xhr.responseText);
            }
        }
        return false;
    }
}

Controller

Posted FormData is available in controller under Request.Form property as key/value pair. Request.Files property contains a collection of HttpFileCollection. Iterate through it to get each files uploaded.

[HttpPost]
public JsonResult Upload()
{
    for (int i = 0; i < Request.Files.Count; i++)
    {
        HttpPostedFileBase file = Request.Files[i]; //Uploaded file
        //Use the following properties to get file's name, size and MIMEType
        int fileSize = file.ContentLength;
        string fileName = file.FileName;
        string mimeType = file.ContentType;
        System.IO.Stream fileContent = file.InputStream;
        //To save file, use SaveAs method
        file.SaveAs(Server.MapPath("~/")+ fileName ); //File will be saved in application root
    }
    return Json("Uploaded " + Request.Files.Count + " files");
}

Method 2 - For legacy browsers

This approach will work on almost all browsers but, you can’t upload multiple files, and file information have to send separately. In this method file is send directly in XMLHttpRequest, and file information is send along with HTTP Headers.

The JavaScript

window.onload = function () {
    document.getElementById('uploader').onsubmit = function () {
        var fileInput = document.getElementById('fileInput');
        var xhr = new XMLHttpRequest();
        xhr.open('POST', '/Home/Upload');
        xhr.setRequestHeader('Content-type', 'multipart/form-data');
        //Appending file information in Http headers
        xhr.setRequestHeader('X-File-Name', fileInput.files[0].name);
        xhr.setRequestHeader('X-File-Type', fileInput.files[0].type);
        xhr.setRequestHeader('X-File-Size', fileInput.files[0].size);
        //Sending file in XMLHttpRequest
        xhr.send(fileInput.files[0]);
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4 && xhr.status == 200) {
                alert(xhr.responseText);
            }
        }
        return false;
    }
}

Controller

[HttpPost]
public JsonResult Upload()
{
    string fileName = Request.Headers["X-File-Name"];
    string fileType = Request.Headers["X-File-Type"];
    int fileSize = Convert.ToInt32(Request.Headers["X-File-Size"]);
    //File's content is available in Request.InputStream property
    System.IO.Stream fileContent = Request.InputStream;
    //Creating a FileStream to save file's content
    System.IO.FileStream fileStream = System.IO.File.Create(Server.MapPath("~/") + fileName);
    fileContent.Seek(0, System.IO.SeekOrigin.Begin);
    //Copying file's content to FileStream
    fileContent.CopyTo(fileStream);
    fileStream.Dispose();
    return Json("File uploaded");
}

Thats it. We’re done

comments powered by Disqus