Ajax like file upload

It is not possible to upload a file to the server through Ajax because the access to the local file system using JavaScript is forbidden but we can use a hidden IFrame in order to obtain an Ajax like behavior. This can be done in the following way:

  1. Create a form element that contains a file upload, an IFrame and a button.
  2. Set the name attribute of the child IFrame to a value (ex: uploadIframe)
  3. Set the target attribute of the containing form element to the name of the child iFrame (uploadIframe). The target attribute specifies where to open the action URL.
  4. In order to know the result of the upload, the IFrame will contain some JavaScript code that will set the result of the operation.

Below is a code example in asp.net MVC:

  • The main form:
    <form action='@Url.Action("UploadFile", "Home")' id="formContainer" method="post"  target="uploadIframe" enctype="multipart/form-data">
        <input type="file" name="fileUpload" id="fileUpload" />              
    </form>
    <input type="submit" value="Upload File" id="buttonUploadFile" name="buttonUploadFile"/>
    <p id="result"></p>
    
    @section scripts {
    <script type="text/javascript">
        $().ready(function () {
            $('#buttonUploadFile').click(function (event) {
                event.preventDefault();
                $('#result').text('Upload started');
                $('#formContainer').submit(); //submit the file to the server
            });
        });
    </script>
    }
    
  • The controller method that will upload the file:
    [HttpPost]
    public ActionResult UploadFile(HttpPostedFileBase fileUpload)
    {
    	try
    	{
    		if (fileUpload != null && fileUpload.ContentLength > 0)
    		{
    			var fileName = Path.GetFileName(fileUpload.FileName);
    			var path = Path.Combine(Server.MapPath("~/uploads"), fileName);
    			fileUpload.SaveAs(path);
    			ViewBag.FileUploadResult = "Success";
    		}
    		else
    			ViewBag.FileUploadResult = "No file to upload";
    	}
    	catch (Exception ex)
    	{
    		ViewBag.FileUploadResult = string.Format("Error: {0}", ex.Message);
    	}
    
    	return View();
    }
    
  • The content of the IFrame page (contains only a script that sets the result of the upload):
    @section scripts {
        <script type="text/javascript">
            $().ready(function () {
                //set the result in the parent page
                window.parent.$('#result').text('@ViewBag.FileUploadResult');
        });
    </script>
    }
    

Download the source code from CodePlex