Tuesday 29 May 2012

Implementing HTML5 Drag & Drop Based File Upload in ASP.NET MVC 3


Implementing HTML5 Drag & Drop Based File Upload in ASP.NET MVC 3


Introduction

HTML5 makes it possible to develop more powerful and more user friendly web applications than we could do ever before. One of the interesting new features is support for drag and drop of files. In the past, if your application needed to provide the possibility to upload files you had to use a file selection chooser. Although this works without issues in all browsers, it is far from user friendly. In native applications, users can interact with files by using drag and drop which is much more intuitive. Luckily for us, HTML5 now also supports this and it is already supported in a number of browsers (Chrome, Firefox, Safari, …).
In this article, I will show you how we can implement drag & drop in an ASP.NET MVC3 web application. We will create a webpage containing a simple drop area that changes of color when the user is dragging a file over the page and we will update the content of the page if the file upload was successful. In order to implement the client side code, we will make use of jQuery and a jQuery plugin called “jquery-filedrop” that simplifies implementing drag & drop based file upload.
Implementation
We start by creating a new ASP.NET MVC 3 web application and we add the file “jquery-filedrop.js” to the Scripts folder of the project. After this is done we modify the default layout “Views/Shared/_Layout.cshtml” to reference our newly added JavaScript library. In order to do is, add the following line to the head tag.
1.<script src="@Url.Content("~/Scripts/jquery.filedrop.js")"type="text/javascript"></script>
I also choose to upgrade to the latest version of jQuery with NuGet; but this is not strictly required…
Now that everything is in place, we can start writing our applicative code. First create a HomeController and an “Index” view for this controller.
Solution View
In the view we will create a div with the id “dropZone”. This will be the area in which users can drop files. Next, we will write some jQuery code that will make the div “droppable”. Thanks to the jQuery plugin we are using, the required code for this is trivial. We just have to call the method “filedrop” with a number of needed parameters.
For our sample application, we provide the URL for the file upload, the parameter name of the files to be used in the HTTP POST, the maximum allowed number of files that can be upload simultaneously and we will listen to some events to add some dynamic behavior to the page. More specifically, if the user is dragging a file over the page we will change the color of the drop zone and we will update a list of successfully updated files.
01.@{
02.ViewBag.Title = "Index";
03.}
04.<style type="text/css">
05.#dropZone {
06.background: gray;
07.border: black dashed 3px;
08.width: 200px;
09.padding: 50px;
10.text-align: center;
11.color: white;
12.}
13.</style>
14.<script type="text/javascript">
15.$(function () {
16.$('#dropZone').filedrop({
17.url: '@Url.Action("UploadFiles")',
18.paramname: 'files',
19.maxFiles: 5,
20.dragOver: function () {
21.$('#dropZone').css('background', 'blue');
22.},
23.dragLeave: function () {
24.$('#dropZone').css('background', 'gray');
25.},
26.drop: function () {
27.$('#dropZone').css('background', 'gray');
28.},
29.afterAll: function () {
30.$('#dropZone').html('The file(s) have been uploaded successfully!');
31.},
32.uploadFinished: function (i, file, response, time) {
33.$('#uploadResult').append('<li>' + file.name + '</li>');
34.}
35.});
36.});
37.</script>
38. 
39.<h2>File Drag & Drop Upload Demo</h2>
40.<div id="dropZone">Drop your files here</div>
41. 
42. 
43.Uploaded Files:
44.<ul id="uploadResult">
45. 
46.</ul>
Now that the view is in place, we can add the required method to our HomeController in order to support the file upload. I choose to call this method “UploadFiles”, it must have a parameter named files (the one we choose in the configuration of our drop zone) and the parameter must be of type “IEnumerable<HttpPostedFileBase>”. In order to keep things simple, we will just write the files to some temporary folder. But of course you can do whatever you want with the uploaded files…

01.public class HomeController : Controller
02.{
03.private const string TempPath = @"C:\Temp";
04. 
05.public ActionResult Index()
06.{
07.return View();
08.}
09. 
10.[HttpPost]
11.public ActionResult UploadFiles(IEnumerable<HttpPostedFileBase> files)
12.{
13.foreach (HttpPostedFileBase file in files)
14.{
15.string filePath = Path.Combine(TempPath, file.FileName);
16.System.IO.File.WriteAllBytes(filePath, ReadData(file.InputStream));
17.}
18. 
19.return Json("All files have been successfully stored.");
20.}
21. 
22.private byte[] ReadData(Stream stream)
23.{
24.byte[] buffer = new byte[16 * 1024];
25. 
26.using (MemoryStream ms = new MemoryStream())
27.{
28.int read;
29.while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
30.{
31.ms.Write(buffer, 0, read);
32.}
33. 
34.return ms.ToArray();
35.}
36.}
37.}
38. 

Conclusion

Now al what rest us, is pressing F5 and testing the application in a browser that already supports this HTML5 specification. I have tested this in the latest version of Google Chrome and Firefox.
image
As I have shown you, it is very easy to implement file drag and drop behavior into your web application, but of course you will still have to support a legacy mechanism as well for people with older browsers.

No comments:

Post a Comment