Html5 multiple Attribute
For multiple file selection, I am using HTML5 <input> type with multiple attribute. It’s a Boolean attribute and it takes values like true or false.
Syntax
<input multiple />
Please remember, that many older versions of IE (IE 9 and below), will not support the multiple attribute. To set the value for the attribute, you may use multiple=true or simply multiple. Set multiple=false to remove multiple selection.
Browser Support:
Chrome 39.0 - Yes | FireFox 34.0 - Yes | Internet Explorer 10 and Above - Yes | Safari – Yes
New HTML5 Input Types and Attributes
Create FileUpload Web API
Start Visual Studio, create a New Project, choose Asp.Net MVC 4 Web Application and name it FileUpload. From the Project Template for New ASP.NET MVC 4 Project select Web API template and press OK.
Create Your First Web API in Asp.Net MVC 4
We don't need a Model for our example here. Therefore, we’ll simply create a controller in our WebAPI.
Open Solution Explorer window in the project. Find Controllers folder, right click it and choose Add and Controller…. In the Add Controller window, type FileUploadController in the Controller Name box. From the Template dropdown list, choose Empty MVC controller and click the Add button. It will create a “.cs” file (.vb for Visual Basic).
using System; using System.Net.http; using System.Web.http; using System.IO; namespace FileUpload { public class FileUploadController : ApiController { [HttpPost()] public string UploadFiles() { int iUploadedCnt = 0; // DEFINE THE PATH WHERE WE WANT TO SAVE THE FILES. string sPath = ""; sPath = System.Web.Hosting.HostingEnvironment.MapPath("~/locker/"); System.Web.HttpFileCollection hfc = System.Web.HttpContext.Current.Request.Files; // CHECK THE FILE COUNT. for (int iCnt = 0; iCnt <= hfc.Count - 1; iCnt++) { System.Web.HttpPostedFile hpf = hfc[iCnt]; if (hpf.ContentLength > 0) { // CHECK IF THE SELECTED FILE(S) ALREADY EXISTS IN FOLDER. (AVOID DUPLICATE) if (!File.Exists(sPath + Path.GetFileName(hpf.FileName))) { // SAVE THE FILES IN THE FOLDER. hpf.SaveAs(sPath + Path.GetFileName(hpf.FileName)); iUploadedCnt = iUploadedCnt + 1; } } } // RETURN A MESSAGE. if (iUploadedCnt > 0) { return iUploadedCnt + " Files Uploaded Successfully"; } else { return "Upload Failed"; } } } }
Note: You must first create a folder in the root directory of your project called locker. You will upload your files in this folder. You may later name the folder as you wish.
Option Explicit On Imports System.Net.http Imports System.Web.http Imports System.IO Namespace FileUpload Public Class FileUploadController Inherits ApiController <HttpPost()> _ Public Function UploadFiles() As String Dim iUploadedCnt As Integer = 0 ' DEFINE THE PATH WHERE WE WANT TO SAVE THE FILES. Dim sPath As String = "" sPath = System.Web.Hosting.HostingEnvironment.MapPath("~/locker/") Dim hfc As System.Web.HttpFileCollection = System.Web.HttpContext.Current.Request.Files For iCnt As Integer = 0 To hfc.Count - 1 ' CHECK THE FILE COUNT. Dim hpf As HttpPostedFile = hfc(iCnt) If hpf.ContentLength > 0 Then ' CHECK IF THE SELECTED FILE(S) ALREADY EXISTS IN FOLDER. (AVOID DUPLICATE) If Not File.Exists(sPath & Path.GetFileName(hpf.FileName)) Then ' SAVE THE FILES IN THE FOLDER. hpf.SaveAs(sPath & Path.GetFileName(hpf.FileName)) iUploadedCnt = iUploadedCnt + 1 End If End If Next If Val(iUploadedCnt) > 0 Then Return iUploadedCnt & " Files Uploaded Successfully" Else Return "Upload Failed" End If End Function End Class End Namespace
The controller has a public function called UploadFiles(), which is called by the Ajax using a POST request. The function returns a string value, as a confirmation, saying if the loaded or has failed.
HtmlFileCollection Class
In the beginning of this article, I have mentioned about the first article that I have written before, about file upload control in Asp.Net’s version 2.0. The reason I mentioned, since I am using the HtmlFileCollection class, introduced in the version with System.io namespace. It provides the necessary methods to get details about files uploaded by a client application. Details such as name of the file, size etc. This class is important.
Finally, add an HTML page to your project. Here, we will add an HTML5 <input> box with type file, with multiple attribute. In-addition we need to add the jQuery script to make an Ajax POST request to the API.
<!DOCTYPE html> <html> <head> <title>Multiple File Upload with HTML5, Ajax and Web API</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script> </head> <body> <form action=""> Select Your Files: <input type="file" id="file" name="file" multiple /> <input id="btUpload" type="button" value="Upload File"/> <p></p> </form> </body>
<script> $(document).ready(function () { $("#btUpload").click(function () { var data = new FormData($('form')[0]); $.ajax({ type: "POST", url: '/api/fileupload/', // CALL WEB API TO SAVE THE FILES. enctype: 'multipart/form-data', contentType: false, processData: false, // PREVENT AUTOMATIC DATA PROCESSING. cache: false, data: data, // DATA OR FILES IN THIS CONTEXT. success: function (data, textStatus, xhr) { $('p').text(data); }, error: function (XMLHttpRequest, textStatus, errorThrown) { alert(textStatus + ': ' + errorThrown); } }); }); }); </script> </html>
In the markup section, I have added the file upload control and a button inside the <form> tag. Later, in the script, I am extracting details in the <form> by using the FormData object.
Ref: Learn more about FormData objects
var formData = new FormData(someFormElement);
To understand jQuery events such contentType and processData, I would ask to you read the article here. Particularly read detail with the header Sending Data to the Server. Both events have a value set as false.
🙂