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

by prashant 28. January 2012 21: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)

If you enjoyed this post, make sure you subscribe to my RSS feed!

Tags: , , , ,

ASP.NET | HTML5 | Jquery | Web

Comments (26) -

Leandro Ribeiro
Leandro Ribeiro Brazil
1/31/2012 7:23:28 AM #

Good job !

Reply

Tam
Tam Vietnam
1/31/2012 5:01:05 PM #

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

Reply

Lam Le
Lam Le Vietnam
1/31/2012 6:11:01 PM #

Thanks!

Reply

Greg
Greg Ukraine
2/1/2012 4:15:09 AM #

IE not support FileAPI

Reply

Imran
Imran United States
2/5/2012 12:54:55 AM #

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

Reply

B
B United States
2/7/2012 6:11:43 AM #

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?

Reply

Imran
Imran United States
2/5/2012 12:55:33 AM #

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

Reply

efyohsikei
efyohsikei United States
2/7/2012 7:53:26 PM #

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

Reply

Prashant
Prashant India
2/7/2012 7:58:40 PM #

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.

Reply

Mr
Mr Spain
2/11/2012 4:16:23 AM #

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

Reply

Sophia
Sophia India
2/18/2012 6:18:02 AM #

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

Thanks

Reply

Prashant
Prashant India
2/18/2012 6:34:23 AM #

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

Reply

Sophia
Sophia India
2/18/2012 9: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

Reply

Prashant
Prashant India
2/19/2012 1:31:54 AM #

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.

Reply

Sophia
Sophia India
2/19/2012 11: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...

Reply

Prashant
Prashant India
2/20/2012 12:26:59 AM #

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

Reply

Sophia
Sophia India
2/20/2012 12:20:49 AM #

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???

Reply

Prashant
Prashant India
2/20/2012 12:25:51 AM #

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.

Reply

Sophia
Sophia India
2/20/2012 12:40:09 AM #

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.

Reply

prashant
prashant India
2/20/2012 7:28:39 PM #

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.

Reply

Sophia
Sophia India
2/20/2012 12:28:56 AM #

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

Reply

prashant
prashant India
2/20/2012 7:36:28 PM #

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).

Reply

Sophia
Sophia India
2/20/2012 10:01:02 PM #

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

Reply

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

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

Reply

Sophia
Sophia India
2/22/2012 3:13:27 AM #

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

Reply

Prashant
Prashant India
2/22/2012 8:42:31 AM #

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.

Reply

Pingbacks and trackbacks (4)+

Add comment




  Country flag
biuquote
  • Comment
  • Preview
Loading


Visit blogadda.com to discover Indian blogs Computers Blogs

About Me

Name of authorPrashant Khandelwal.
Programmer and tech enthusiast. More...

Feeds Subscribe Twitter Facebook Google Plus Linked In Delicious

My Visual Studio Achievements

Badges

MVB

MVP Blog Badge.

HTML5 Powered with CSS3 / Styling, Graphics, 3D & Effects, Multimedia, Performance & Integration, Semantics, and Offline & Storage

Month List

Blog Stats

344,739 Hits

Adverts

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2012

Creative Commons License