Upload Multiple Files With Progress Using Uploadify

I previously posted on how to use Uploadify to upload files. The previous post covered really well how to upload single files to an ASP.NET MVC controller using Uploadify. This post will expand on that a bit. First we will revisit how to upload multiple files using a single HTML input element. Then the case of uploading multiple files using multiple HTML input elements. Finally, how to upload multiple files while posting form data.

Here are links to the demo pages for the Single and Multiple file uploads.

Getting Started

If you are not familiar with Uploadify here is a description from their web site:

Uploadify is a jQuery plugin that integrates a fully-customizable multiple file upload utility on your website. It uses a mixture of JavaScript, ActionScript, and any server-side language to dynamically create an instance over any DOM element on a page.

If will first need to download the Uploadify code. I simply unzipped it into my ‘scripts’ folder as shown below:

Any page that uses Uploadify will need to include the following lines in the ‘head’ section:

The Uploadify object supports a number of properties, events, and methods. Visit their page for in-depth information. The configuration that allows multiple files to be selected is the ‘multi’ option. Setting this to ‘true’ enables multiple file selection as shown below.

That results in the following:

The ‘Upload Files’ button is wired up to call the ‘uploadifyUpload’ method on the Uploadify object. This begins the upload process. The file uploads happen asynchronously and not in a guaranteed to arrive in a specified order. All selected files are handled by a single ASP.NET MVC action method:

This works great if the same processing can be applied to all files. If you require the files to be dispatched out to different processors based upon their type then this probably will not work. In this case, you will need to use multiple HTML input elements.

The ‘button’ element is again used to start the upload processing. Each ‘input’ element has a unique ‘name’ attribute. If this were posted back in a normal HTML ‘form’ then this ‘name’ attribute would follow the file to the server where the file processing could be based upon the value of the ‘name’ attribute. Here is the JavaScript that configures this scenario:

In this case, each input element is configured to only allow a single file to be selected (‘multi’:false). The key configuration in this case is the ‘scriptData’ option. This options allows JSON data to be sent back to the server along with the file. In this case we send a ‘packageId’ (created on the first line) and a ‘type’. The ‘packageId’ is used to associate the files into groups on the server. The ‘type’ variable is the ‘input’ element’s ‘name’ attribute and allows the server side code to differentiate the files. The ASP.NET MVC controller now looks like the following:

This method not only receives the file, but also the JSON data sent by Uploadify. The JSON data is then used to add the incoming file to a particular package. The specific implementation of the packaging system is not important (and not shown), but the key is that the server has the information necessary to implement the packaging feature. The above code could just as easily dispatched the file to various processors based upon the ‘type’ parameter.

The above works great for processing files based upon their types. The next challenge is processing files and form data where the form data provides important context for processing.

Multiple Files With Multiple HTML Input Plus Form Data

Assume we have an HTML ‘form’ that accepts multiple files and the first/last name of the user. The files must be processed based upon who uploaded the files. Therefore the first/last name data is important and required before processing can occur. Here is the HTML defining the form:

Traditionally (without Uploadify involved) this form would POST all the data to a single ASP.NET MVC action method and no upload progress would be provided. Hooking up Uploadify provides the desired progress indicators, but now the files are uploaded ‘out of band’. Some special handling is necessary to keep the files and the form data associated. Here is the JavaScript that configures the form:

The Uploadify elements are configured nearly the same as before using the ‘scriptData’ option to send back the ‘packageId’ and the ‘type’ information as JSON. However, in this case the ‘packageId’ is prepended to the form as an HTML hidden ‘input’ element (first three lines). In addition the Uploadify ‘onComplete’ callback now calls the ‘incrementUploadCount’ function (covered below) and the HTML submit button is wired up to call the ‘submit’ function.

The above code defines the client side pipeline that eventually upload the files and submit the form. The submit button calls the ‘submit’ function. In the ‘submit’ function, the form is first validated. Then the number of files being uploaded is determined and a counter is set to zero. Finally, the Uploadify elements are triggered.

Each Uploadify element calls the ‘incrementUploadCount’ upon successfully uploading the file to the server. Once all the files have been uploaded, the form is submitted. Here is the ASP.NET MVC action methods that are needed:

The ‘Upload2’ action method is the same as before. It collects the uploaded files into a package. The ‘ProcessForm’ action method receives the rest of the form data along with the ‘packageId’. The ‘packageId’ is used to request the ‘Package’ that contains the associated files. The form data is then added to the ‘Package’. Once complete the ‘Package’ can be sent off for processing as a whole. In this case, it is simply sent to a ‘View’ to render a receipt page.

Summary

Uploading multiple files with progress using Uploadify is an option. Depending on your requirements there can be additional complexity. In this post, we have covered a way of accomplishing multiple file uploads under various requirements. As always, if you have feedback post a comment.

[ Update ]

Here is the package manager that I put together. I did not put a lot of thought or testing into this implementation.>

Could you put here the source code (maybe an example of 1 html input with multiple file uploads plus form data).
I am trying to upload a file along with form data , the file gets uploaded put the action of the form doesnt execute , i cant even get in the increment function i dont know why.

I put all the client-side code in the page (javascript, css, html) http://bobcravens.com/Uploadify/Test/Multiple. Go there and view source. On that page are the ASP.NET MVC controllers that I am using. If you post your code (maybe to jsFiddle.net) I can help a bit more.

Hi,
I’m looking for a way for the upload folder to be determined by user input.
User enters an email address, then selects files to be uploaded. Once selection is made the click and upload to a newly created folder named from the MD5 of the email address.
Any help would be greatly appreciated!
All the best,

The post shows how to upload multiple files in a couple of different ways. The last example in the post (and the demo page) is probably close to what you want. Instead of ‘First Name’ and ‘Last Name’ substitute your ‘Email Address’ input. After all the files are uploaded (these are asynchronous) the form will be submitted. On the submit handler, you can do the work of creating your folder and saving the files. You should know that the MD5 hash does produce collisions. It may be at an acceptable rate for you. If this is public facing, you may want to use a different hash algorithm.

The source code is really just what is on the demo page (http://bobcravens.com/Uploadify/Test/Multiple). The demo page shows the exact controllers. If you right-click and view-source, you have the html/javascript. What are the difficulties that you are having?

Hello,
I was wondering about the importance of the ‘package’? I am trying to implement this but my problem when i upload nothing is uploaded. I tried debugging to see where the error is at and when i hit my controller i notice that the files count is always zero no matter how many file I’ve actually selected. Everything seems right but cannot really tell where the issue is. Are you willing to help if i post parts of my code for the upload?

The package system is used to keep the grouping of files together and then take some final action on the group. I am not certain of the exact issue that you are having. If you post some parts, I can try to take a look.