posted on 08 January 2013

2 comments

Multiple file upload with Asp.Net 4.5 (Without JavaScript)

TAGS: Asp.Net,Asp.Net 4.5,C#

One of the small little gems we recently discovered in .Net 4.5 is the ability to upload multiple files using the native .Net FileUpload control and some Html 5 support. I'll run you through the basics of getting this working, as well as a fallback for older browsers.

ASPX implementation

Firstly, create a new website and make sure your site is targeting .Net 4.5 (I’m not going to delve into how you would do this, the resources available here will be more than enough to get you going).

On the ASPX page (or control), you need to declare a FileUpload control and a button to upload your files. The syntax for this is pretty straight forward, as shown below:

<form id="form1" runat="server">
   <div>
      <asp:FileUpload runat="server" ID="fuImage" AllowMultiple="true" />
      <asp:Button runat="server" ID="btnUpload" Text="Upload" OnClick="btnUpload_Click" />
   </div>
</form>

Notice the AllowMultiple attribute on the FileUpload control. This will render the following HTML:

<input type="file" multiple="multiple" name="fileUploadImage" id="fileUploadImage" />

​The new multiple attribute tells your browser to allow multiple files to be selected if supported (without this attribute, you will only be able to select one file). Once you have selected multiple files, your browser should display the file count or the file list (this differs from browser to browser. Chrome shows the total file count, Firefox the list of files in a textbox and Opera does the same as Firefox).

C# code behind

In the Click event handler for the button you need to specify the following code. Essentially it uses a new property called HasFiles (yes I know, it's not far off from the previous property HasFile which is still in use and perfectly valid). One thing to note, if you have selected one or ten files, the HasFiles will return true and if no files have been selected, it will return false.

protected void btnUpload_Click(object sender, EventArgs e)
{
    if (fuImage.HasFiles)
    {
        foreach (HttpPostedFile file in fuImage.PostedFiles)
        {
            // save the file down using file.SaveAs(...);
        }
    }
}

Once we are satisfied there are files to upload, you can iterate the files using the new PostedFiles property and process each file individually as shown in the code above. Now you might be wondering, where is the magic happening here? Is .NET injecting loads of magical Javascript to achieve such a wondrous feat? No, not at all. It’s all pretty native HTML stuff happening under the bonnet. Using Chromes Network inspector, we can see the following information being sent with the post request:

------WebKitFormBoundaryrQmJHEm9vGrGAWyW
Content-Disposition: form-data; name="fuImage"; filename="Hydrangeas.jpg"
Content-Type: image/jpeg

------WebKitFormBoundaryrQmJHEm9vGrGAWyW
Content-Disposition: form-data; name="fuImage"; filename="Chrysanthemum.jpg"
Content-Type: image/jpeg

------WebKitFormBoundaryrQmJHEm9vGrGAWyW
Content-Disposition: form-data; name="fuImage"; filename="Desert.jpg"
Content-Type: image/jpeg

Multiple files are listed in the posted values of the request (split by boundaries similar to MIME encodings) which .NET 4.5 interprets correctly and provides programmatic access.

Ok, I know what you are thinking… ‘That’s amazing, but what about older browsers’? And so the story continues...

Fall-back support for older browsers

In order for the above functionality to support older browsers, essentially all you need to change is… nothing. Yip, that’s right. The above code will work even for older browsers. An older browser will only allow you to select one file. The HasFiles property will still return true and the PostedFiles property will only contain the one file meaning your code will only iterate once, hence it will all still work.

This really is such a simple method of adding a very powerful feature to your software without writing any Javascript or using any Flash. The end user experience is greatly improved and you can save your users a ton of time.

Hope this tutorial helped and, as always, feedback welcome.

Gordon

Head of Development for Cergis.

Find out more about Gordon here.

2 comments

Rex said:

This is extremely helpful...thanks dude.

Tim said:

Awesome! Though Microsoft really should have introduced this in a much earlier version of visual studio. Better late than never I guess.

add your comment

Email me when other users reply