HTML5 File Drag and Drop Upload With jQuery and ASP.NET

by prashant 28. January 2012 12:00

I came across an article on Tutorialzine which demonstrate file drag and drop upload with jQuery and PHP. As a curious reader, I downloaded the sample files and took a look and also get it running on my LINUX VM. It worked like a charm. But I am a Windows user and .NET programmer, the question is how can I do the same in ASP.NET?

If someone out there can do something in PHP then I can do that in .NET!!

Who said the above line??.....ME!!??.....oh yeah!!! So, to get myself started I used the same downloaded files that I used to check the PHP version of the file drag and drop. The only thing that we are not going to re-use out of these files is the php file. You can delete it if you wish or keep it, it's of no harm to our ASP.NET app.

Updating The jQuery Part

This example uses an awesome plugin from Weixi Yen and you can found the plugin and it's sample usage (documentation) on GitHub. The basic or I should say the default functionality provided by this plugin is to allow users to drag and drop the files from desktop to the browser. But before you actually get started with the plugin, I strongly recommend that you make yourself familiar with the parameters and configurations of the plugin.

Open the script.js file and change the URL to point to the web service or the page which will upload the posted file. Here I want you to pay attention to the javascript function named createImage. This method accepts the file as a parameter and returns the image or file data in Base64 format. This is the data which actually gets posted when the user drops a file to the upload area on the web page. This is all up to you whether you want to use a web service or a normal web page to accept the posted file/data. Here is my script.js file looks like after the changes.

$(function () {

    var dropbox = $('#dropbox'),
		message = $('.message', dropbox);

    dropbox.filedrop({
        paramname: 'pic',
        maxfiles: 5,
        maxfilesize: 100,
        //url: '/Uploader.asmx/Upload',
        url: '/Default.aspx',

        uploadFinished: function (i, file, response) {
            $.data(file).addClass('done');
        },

        error: function (err, file) {
            switch (err) {
                case 'BrowserNotSupported':
                    showMessage('Your browser does not support HTML5 file uploads!');
                    break;
                case 'TooManyFiles':
                    alert('Too many files! Please select 5 at most! (configurable)');
                    break;
                case 'FileTooLarge':
                    alert(file.name + ' is too large! Please upload files up to 2mb (configurable).');
                    break;
                default:
                    break;
            }
        },

        // Called before each upload is started
        //        beforeEach: function (file) {
        //            if (!file.type.match(/^image\//)) {
        //                alert('Only images are allowed!');

        //                // Returning false will cause the
        //                // file to be rejected
        //                return false;
        //            }
        //        },

        uploadStarted: function (i, file, len) {
            createImage(file);
        },

        progressUpdated: function (i, file, progress) {
            $.data(file).find('.progress').width(progress);
        }

    });

    var template = '<div class="preview">' +
						'<span class="imageHolder">' +
							'<img />' +
							'<span class="uploaded"></span>' +
						'</span>' +
						'<div class="progressHolder">' +
							'<div class="progress"></div>' +
						'</div>' +
					'</div>';


    function createImage(file) {

        var preview = $(template),
			image = $('img', preview);

        var reader = new FileReader();

        image.width = 100;
        image.height = 100;

        reader.onload = function (e) {

            // e.target.result holds the DataURL which
            // can be used as a source of the image:
            //alert(e.target.result);
            image.attr('src', e.target.result);
        };

        // Reading the file as a DataURL. When finished,
        // this will trigger the onload function above:
        reader.readAsDataURL(file);

        message.hide();
        preview.appendTo(dropbox);

        // Associating a preview container
        // with the file, using jQuery's $.data():

        $.data(file, preview);
    }

    function showMessage(msg) {
        message.html(msg);
    }

});

Check out line number 10 and 11. I have change the url parameter to the one where my files are going to be posted. It can be a webservice or just a normal web page. The other two parameters maxfiles and maxfilesize defines the number of file that can be uploaded asynchronously and maximum size of the file that can be uploaded in MBs respectively. Also note that the demo that you download from the original source will have a validation that the files that are being uploaded by the user should only be images. If you want to override this rule then uncomment the lines from 33-42. This is it from the jQuery/script part. Now time to move on the server side code.

The Server Side Code

To remind you again that we are posting a file to a web service or to a web page and therefore that code for our web service or on our page will look something like this:

If you are using a web service to upload the posted file:

[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string Upload()
{
       HttpContext postedContext = HttpContext.Current;
       HttpPostedFile file = postedContext.Request.Files[0];
       string name = file.FileName;
       byte[] binaryWriteArray = new
       byte[file.InputStream.Length];
       file.InputStream.Read(binaryWriteArray, 0,
       (int)file.InputStream.Length);
       FileStream objfilestream = new FileStream(Server.MapPath("uploads//" + name), FileMode.Create, FileAccess.ReadWrite);
       objfilestream.Write(binaryWriteArray, 0,
       binaryWriteArray.Length);
       objfilestream.Close();
       string[][] JaggedArray = new string[1][];
       JaggedArray[0] = new string[] { "File was uploaded successfully" };
       JavaScriptSerializer js = new JavaScriptSerializer();
       string strJSON = js.Serialize(JaggedArray);
       return strJSON;
}

Nothing fancy or complicated in the above code. Remember, the files will send to the web service one by one and not in a collection and this is the reason I am working with one file at a time and not with file collections. In my case I have used a web service that return me JSON result which I can show it to the user, though it is not necessary, but just in case if you want to have one for your web service you need to use 2 using statements:

  • using System.Web.Script.Serialization;
  • using System.Web.Script.Services;

If you are using a web page to upload the posted file:

HttpContext postedContext = HttpContext.Current;
HttpPostedFile file = postedContext.Request.Files[0];
string name = file.FileName;
byte[] binaryWriteArray = new
byte[file.InputStream.Length];
file.InputStream.Read(binaryWriteArray, 0,
(int)file.InputStream.Length);
FileStream objfilestream = new FileStream(Server.MapPath("uploads//" + name), FileMode.Create, FileAccess.ReadWrite);
objfilestream.Write(binaryWriteArray, 0,
binaryWriteArray.Length);
objfilestream.Close();
string[][] JaggedArray = new string[1][];
JaggedArray[0] = new string[] { "File was uploaded successfully" };
JavaScriptSerializer js = new JavaScriptSerializer();
string strJSON = js.Serialize(JaggedArray);
Response.Write(strJSON);
Response.End();

Same code as I have for the web service, put the above code on the page_load event.

Caution!!

While I was working around with the above code and configuration of the plugin I came across an error that won't allow me to upload heavy files or I should say large files. The error that I received is:

System.Web.HttpException: Maximum request length exceeded

To overcome this error you have make the below configuration in your web.config file inside <system.web>

<httpRuntime maxRequestLength="102400" executionTimeout="1200" />

A word of caution here, though it will solve your problem but:

  • If the maxrequestLength is TOO BIG then you will be open to DOS attacks.
  • The default executionTimeout is 360 seconds. Change it accordingly and only if you are running on really slow connections.

This is it, if you have followed the steps above then try uploading some file. And if you haven't and lazy to put all the pieces together then download the code from the below and try it.

Download: HTML5DragNDrpFileUpload.zip (58.15 kb)

Comments (46)

JoshN
JoshN
9/1/2012 1:06:34 AM #

I think the javascript code is being ignored, nothing activates when I drop a picture into the dropzone. It just opens a new firefox tab. I'm going to try using a modal popup on my master page I think.

JoshN
JoshN
8/31/2012 5:28:06 AM #

I was wondering if anyone has tried to use this on a page that has a master page? When I drop the image on the "dropzone" a new tab in Firefox opens and displays the picture. I can run this demo project and it works just fine so I figured it has something to do with the Master page I'm using. Any advice? Thanks!

Notaes
Notaes
8/31/2012 2:22:53 PM #

Muy buena información, me encanta el Html 5, gracias por tu post.

Prashant
Prashant
8/31/2012 9:24:52 PM #

I think the code will mostly the same, though I have not tried it yet.

Prashant
Prashant
8/31/2012 9:34:08 PM #

If you look at the code above, you can see that I have commented the above code where there is a regex that checked whether the uploaded file is of image type or not. If you just want to implement the drag & drop for images only then un-comment the code to implement the check.

Oro
Oro
8/30/2012 10:06:42 PM #

I need something that only accepts drag and drop photos .... Do you know something like that?

manju
manju
8/21/2012 7:51:10 AM #

I was run the code but an error occured Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index

louis vuitton borse
louis vuitton borse
8/18/2012 9:00:20 AM #

Qualcosa di strano sta accadendo. Quando provo ad eseguire pagina default.aspx quindi la pagina index.html è indicata.

Prashant
Prashant
8/18/2012 11:33:12 AM #

È perché la pagina default. aspx gestisce la richiesta di caricare i file. Se si apre la pagina in modalità di progettazione di Visual Studio, si vedrà nulla su quella pagina. D'altra parte la pagina index. html è quello dove si deve usare drag and drop funzionalità è implementata per caricare i file.

mark
mark
7/17/2012 6:59:24 PM #

drag and drop doesnt work in default.aspx.when i delete the index.html and paste the div dropbox and all the link to script in default.aspx

Bhaskar
Bhaskar
7/5/2012 5:46:05 PM #

It has been really helpful. I have a problem, when I am executing the code on my local machine in dev environment, it is working fine. But, when I move it to IIS and try running from any machine, I get an error in uploading the files. I get the error as POST http://XXX.XXX.XXX.XXX/Default.aspx 404 (Not Found) jquery.filedrop.js:311 XMLHttpRequest.sendAsBinary jquery.filedrop.js:311 send jquery.filedrop.js:215 Uncaught SyntaxError: Unexpected token < jquery-1.6.3.min.js:2 e.extend.parseJSON jquery-1.6.3.min.js:2 xhr.onload Can you kindly help me?

yoshikuni
yoshikuni
6/3/2012 6:17:10 AM #

how can I get filename save to database? please help me.

Prashant
Prashant
6/3/2012 9:48:55 PM #

If you check the code for the web service and the web page method then check out the below line in the code. string name = file.FileName;

SoSO
SoSO
5/8/2012 2:13:59 PM #

you should start index.html and not default.aspx

SoSO
SoSO
5/8/2012 2:19:30 PM #

Hi... can I use this exampe to upload a file without drag&drop??? I want to use <input type="file">......

Jeff Hunag
Jeff Hunag
4/16/2012 12:35:22 PM #

Thank you for your article.

Dan Russell
Dan Russell
4/12/2012 12:43:52 PM #

I discovered this same issue with the progress bar in the ASMX version. It was due to the Json response string still being wrapped in XML: "<?xml version="1.0" encoding="utf-8"?><string xmlns="http://tempuri.org/">;[["File was uploaded successfully"]]</string>" The '<' character throws an error in JavaScript and kills the script. However, the files were still being successfully uploaded. To resolve the issue, I used the solution outlined here: stackoverflow.com/.../asp-net-ajax-returning-xml-when-json-specified. I haven't identified the root of the issue: why is XML being returned when the WebMethod is decorated with a ResponseFormat of Json? If I do, I'll report back here.

priya
priya
2/28/2012 7:59:54 AM #

I need drag and drop file upload in visual studio 2005. please urgent

prashant
prashant
2/28/2012 6:25:54 PM #

What is the error/complications you are facing while implementing file upload using drag & drop?

priya
priya
2/27/2012 4:55:46 PM #

I am trying to Upload the Dragged file in web application which is created by using visual studio 2005 . How to achive the drag and drop file upload process. Please help me.

Sophia
Sophia
2/21/2012 6:13:27 PM #

No, I am not getting any error message. When I drop the images then the progress bar starts and stops when reaches upto 45%-50%. And when I see the Uploads folder after a while then I do not see any image there. Thanks

Prashant
Prashant
2/21/2012 11:42:31 PM #

If progress bar stops at 40%-50% then this means that there is an exception either in the script. Could be possible that you have not set the path url path for the service correctly. If you are using chrome then I suggest you to look at the console to find where the problem is.

prashant
prashant
2/20/2012 10:28:39 AM #

I don't know about firefox, but I did a search and found this link. http://demos.hacks.mozilla.org/openweb/FileAPI/ It is clearly stated that you must be using 3.6 beta version of Firefox to avail the use of FileAPI. I am not using Firefox and therefore I cannot tell more about that.

prashant
prashant
2/20/2012 10:36:28 AM #

Why you are trying to run default.aspx? The reason I used default.aspx in the above example to show that users can also upload files in ASP.NET using a normal .aspx page and also through a web service. If you check the default .aspx there is nothing implemented on that page. As I mentioned earlier that IE does not support FileAPI at the moment. To upload only images you need to uncomment the following javascript code: // Called before each upload is started // beforeEach: function (file) { // if (!file.type.match(/^image\//)) { // alert('Only images are allowed!'); // // Returning false will cause the // // file to be rejected // return false; // } // }, You can find the above code from line number 33-42 (you can see the highlighted lines of code in the post above).

Sophia
Sophia
2/20/2012 1:01:02 PM #

Thanks... I got your point. But the only problem I am facing is that [b]only image are not being uploaded.[/b]

prashant
prashant
2/20/2012 2:46:38 PM #

Is there any specific error you are getting while uploading files?

Sophia
Sophia
2/19/2012 2:58:51 PM #

Hi, It is not working. And why index.html file is being displayed, even I have run the default.aspx file. Also on Index.html page I tried to drop jpg file but it did not work. Kindly help me...

Sophia
Sophia
2/19/2012 3:20:49 PM #

A very strange thing is happening. Drag and drop is working only with chrome and not with the IE or Mozila. Also as project is configured to upload images, it is uploading other files except for images. Please tell me what wrong is happening???

Prashant
Prashant
2/19/2012 3:25:51 PM #

If you read Greg comment above you will know that IE does not support FileAPI. Also how you have configured the code to upload only images. Have you uncomment the javascript check as I shown in the code above to enable the check.

Prashant
Prashant
2/19/2012 3:26:59 PM #

Use the browser which supports FileAPI. Old browser don't support FileAPI.

Sophia
Sophia
2/19/2012 3:28:56 PM #

Hi, Something strange is happening. When I try to run default.aspx page then index.html page is shown. Also drag and drop is working with chrome only not with ie or mozila, and project is configured to upload images but it is uploading other files except for images. Please tell me what wrong is happening?? Thanks

Sophia
Sophia
2/19/2012 3:40:09 PM #

Ok IE does not support fileAPI, but what about mozila firefox. And my question was that the project is primarily configured to upload images but other files are being uploaded but not the images with the default project configuration.

Sophia
Sophia
2/18/2012 12:58:12 PM #

yes, I downloaded the code and tried to run but it was giving me error. When I debugged it then I found that second line (HttpPostedFile file = postedContext.Request.Files[0];) in page_load event breaks, and it is obvious because when we first run the application and page loads then there is no any file that we have dragged and dropped in UI. Please tell me how to modify the code so that the code runs only when we have dropped some files in dropping area. Thanks

Prashant
Prashant
2/18/2012 4:31:54 PM #

Well I missed that part in the example above. Thanks for pointing out. To avoid this check if the page is postback using Page.IsPostback method on the page load event. This will solve your problem.

Sophia
Sophia
2/17/2012 9:18:02 PM #

Hi, I am getting error while running default.aspx file. error is index is out of range... please help me!!! Thanks

Prashant
Prashant
2/17/2012 9:34:23 PM #

Are you using the same code as I have posted above?

Mr
Mr
2/10/2012 7:16:23 PM #

Hi! Nice script! I have a problem though, I am trying to use a querystring to use as an id to rename the file. I will check for pictures connected to this id in my db and then give the new picture a unique name and id. I have changed the index.html to an aspx file that sets the id as value on a hidden form element. The script needs to pick up this value so that I can use it in the Default.aspx.cs to rename the file and save changes to my db. If anyone has done something similar, please share ;) Thanks

efyohsikei
efyohsikei
2/7/2012 10:53:26 AM #

I need something that only accepts drag and drop photos .... Do you know something like that?

Prashant
Prashant
2/7/2012 10:58:40 AM #

Take a look at the above script on line number 33 to 42. It has a simple check which gets fired before the actual upload process gets fired. If you only want to upload images then un-comment these lines and then you will be able to upload images only.

B
B
2/6/2012 9:11:43 PM #

I'm trying to add a DB insert for each file uploaded, I've put the following code in my page load of Default.aspx following his example SqlDataSource fileInsert = new SqlDataSource(); fileInsert.ConnectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ToString(); fileInsert.InsertCommandType = SqlDataSourceCommandType.Text; fileInsert.InsertCommand = "INSERT INTO uploads (filename, date, filetype, height, width, uploadGroup) VALUES (@filename, @date, @filetype, @height, @width, @uploadGroup)"; fileInsert.InsertParameters.Add("filename", "filename"); fileInsert.InsertParameters.Add("date", DateTime.Now.ToString()); fileInsert.InsertParameters.Add("filetype", "jpg"); fileInsert.InsertParameters.Add("height", "1"); fileInsert.InsertParameters.Add("width", "1"); fileInsert.InsertParameters.Add("uploadGroup", "1"); fileInsert.Insert(); unfortunately this isn't working, or throwing any errors. I have it write after the "Response.End()" in his example, any ideas?

Imran
Imran
2/4/2012 3:54:55 PM #

@Tam, See this library which fallback into silver light for IE users.

Imran
Imran
2/4/2012 3:55:33 PM #

Here is the link, https://github.com/MrSwitch/dropfile

Tam
Tam
1/31/2012 8:01:05 AM #

How to fix to this work in IE7-8-9. Please help me

Lam Le
Lam Le
1/31/2012 9:11:01 AM #

Thanks!

Greg
Greg
1/31/2012 7:15:09 PM #

IE not support FileAPI

Leandro Ribeiro
Leandro Ribeiro
1/30/2012 10:23:28 PM #

Good job !

Add Comment

*
*
 

Visit blogadda.com to discover Indian blogs Computers Blogs