Uploading Folders in HTML5 Uploader ASP.NET

Uploading folders is extremely useful when users are allowed to upload large amounts of files. This topic describes how to set up uploading folders on client side and restore folders structure on a server.

Uploading Folders on Client Side

Configuring folders uploading in HTML5 Uploader is as simple as adding only one property - ImageUploaderFlash.FolderProcessingMode to say to the control how to deal with folders. Let us describe all FolderProcessingMode possible values:

  • None - turn folder uploading off.
  • Mixed - allows both files and folders.
  • Folder - allows only folders.

You can also use the values accepted by Java/ActiveX uploader (in this case Skip is the same as None while Show and Upload - Mixed).

Important

HTML5 Uploader supports folder uploads only in Chrome. If you want to use it with other browsers as well, it is recommended to use both Java/ActiveX and HTML5/Flash uploaders together as discussed below.

When you turn this feature on, it affects not only the open file/folder dialog, but also drag-and-drop functionality. All its subfolders become selected recursively.

Note

There is a limitation in Google Chrome for a number of files added when you drop a folder - it adds not more than 100 files per a folder. This limitation is not applied if the user adds a folder using a dialog. There is no official information from Google regarding this issue, so it is probably happens only on particular versions.

Here is an example how to use the FolderProcessingMode property:

ASP.NET
<aur:ImageUploaderFlash ID="Uploader1" runat="server" FolderProcessingMode="Upload" />

As a result, if a user selects a whole folder, all the files in this folder will be recursively added to the upload pane; so a user can clearly see all the files selected at once. When a user starts the uploading process, the structure of this folder will be sent to a server via relative paths to each of the selected files. For instance, if a user sends a MyDocuments folder, which contains a MyPhotos subfolder, all files inside this subfolder will be sent to a server along with MyDocuments\MyPhotos\filename relative paths and all files contained directly in the MyDocuments folder will have MyDocuments\filename relative paths. In opposite, if the user selects an individual file inside the MyDocuments, no folder name is appended ot the file name.

If you need to access the folder structure of a selected file before the upload, from your JavaScript code, you can use (both getter and setter).

Note

HTML5 Uploader sends only relative paths along with uploaded files rather than full paths. Unfortunately, browsers don't allow receiving full paths from a file system because of the security/privacy reasons.

Restoring Folders Structure on Server Side

There are three ways to restore folders structure on server side corresponding to approaches described in the Saving Uploaded Files in HTML5/Flash Uploader ASP.NET topic. Let us examine each of them in detail, beginning with the simplest one.

Restoring Folders Structure Automatically

In this case all the uploaded files and folders are saved on a server automatically. All you need is just to enable the autosave feature for chosen HTML5/Flash Uploader ASP.NET server-side component. If you do not know what component to choose, either ImageUploaderFlash, UploadRequest, or UploadHandler, please, see the server-side components section. In order to configure the component set the Autosave Uploader.AutoSave UploadRequest.AutoSave UploadHandler.AutoSave property to true and specify the DestinationFolder Uploader.DestinationFolder UploadRequest.DestinationFolder UploadHandler.DestinationFolder with a path where uploaded files and folders should be saved. For more information on this approach see the uploading files to the specified folder section.

Here is the example which allows uploading folders and enables autosave for the ImageUploaderFlash control.

ASP.NET
<aur:ImageUploaderFlash ID="Uploader1" runat="server" FolderProcessingMode="Mixed" 
    Autosave="true" DestinationFolder="~/Catalog" />

Restoring Folders Structure Using Server-side Components

Here you recreate uploaded folders manually using one of the following server-side components: ImageUploaderFlash, UploadRequest, or UploadHandler. If you are unfamiliar with these classes, please, read the server-side components section first. Each of these components exposes the FileUploaded Uploader.FileUploaded UploadRequest.FileUploaded UploadHandler.FileUploaded and AllFilesUploaded Uploader.AllFilesUploaded UploadRequest.AllFilesUploaded UploadHandler.AllFilesUploaded events allowing you to access all the uploaded file details via the UploadedFile properties. In particular, a relative path is available through the UploadedFile.RelativePath property. For more information about these events see the extended processing of uploaded data section.

The following example uses the FileUploaded Uploader.FileUploaded UploadRequest.FileUploaded UploadHandler.FileUploaded event to create a folder for the currently uploaded file (if it was uploaded within a folder, of course) and save this file in it.

ASP.NET
<aur:ImageUploaderFlash ID="Uploader1" runat="server" FolderProcessingMode="Mixed" 
    OnFileUploaded="FileUploaded" />
C#
protected void FileUploaded(object sender, Aurigma.ImageUploaderFlash.FileUploadedEventArgs e)
{
    string absPath = System.IO.Path.Combine(Server.MapPath("Gallery/"), e.UploadedFile.RelativePath);
    
    System.IO.DirectoryInfo destFolder = new System.IO.DirectoryInfo(absPath);
    if (!destFolder.Exists)
        destFolder.Create();

    string fileName = System.IO.Path.Combine(destFolder.FullName, e.UploadedFile.SourceName);
    e.UploadedFile.ConvertedFiles[0].SaveAs(fileName);
}

Restoring Folders Structure Using POST Fields Data

This method requires only a standard ASP.NET Request object to get a relative path to the uploaded file. The path is stored in the SourceName field of received POST request, so you can use it to restore folder structure manually. We also recommend you to use the PostFields class to get names of POST fields. For more information about saving files this way, see the parsing POST requests using standard ASP.NET Request object section.

Note

HTML5/Flash Uploader sends a HEAD request before the POST one to check if authentication is needed. So, you should check the type of Request and handle POST requests only.

The example below parses the received request via the standard ASP.NET Request object, creates uploaded folders, and saves files to them.

C#
protected void Page_Load(System.Object sender, System.EventArgs e)
{
    if (string.Equals(Request.RequestType, "POST"))
    {
        int fileCount = int.Parse(Request.Params[Aurigma.ImageUploaderFlash.PostFields.PackageCount]);
        for (int i = 0; i < fileCount; i++)
        {
            if (Request.Files[string.Format(Aurigma.ImageUploaderFlash.PostFields.File, 0, i)] != null)
            {
                string fileName = System.IO.Path.Combine(Server.MapPath("Uploads/"), 
                    Request[string.Format(Aurigma.ImageUploaderFlash.PostFields.SourceName, i)]);
                Request.Files[string.Format(Aurigma.ImageUploaderFlash.PostFields.File, 0, i)].SaveAs(fileName);
            }
        }
    }
}

Using both HTML5 and Java uploaders together

Unfortunately the folder selection functionality works only in Google Chrome browser. If you enable the folder uploading and open the uploader in, say, Firefox or IE, it will ignore the FolderProcessingMode property.

How to handle this? The answer is using HTML5 Uploader in Chrome while load Java/ActiveX uploader in other browsers. Like this:

ASP.NET
<asp:Content ID="Content2" ContentPlaceHolderID="content" runat="Server">
    <aurja:UploadRequest runat="server" OnFileUploaded="Uploader1_FileUploaded"></aurja:UploadRequest>

    <% if(Request.Browser.Browser=="Chrome"){ %>
    <aurhf:ImageUploaderFlash ID="UploaderHF1" runat="server"
        LicenseKey="<%$ AppSettings:ImageUploaderLicenseKey %>" FolderProcessingMode="Upload"
        Width="100%" Height="500px" EnableDescriptionEditor="false">
        <Converters>
            <aurhf:Converter Mode="*.*=SourceFile" />
        </Converters>
        <UploadPane ViewMode="Tiles">
        </UploadPane>
        <UploadSettings />
    </aurhf:ImageUploaderFlash>
    <% }else{ %>
    <asp:button ID="Button1" runat="server" Text="Add Folder" OnClientClick="Aurigma.ImageUploader.uploader('ctl00_content_UploaderJA1').uploadPane().addFolders();return false; " />
    <aurja:Uploader ID="UploaderJA1" runat="server" 
        LicenseKey="<%$ AppSettings:ImageUploaderLicenseKey %>" FolderProcessingMode="Upload"
        Width="100%" Height="500px" EnableImageEditor="false" EnableRotation="false" PaneLayout="OnePane">
        <Converters>
            <aurja:Converter Mode="*.*=SourceFile" />
        </Converters>
        <FolderPane Height="500" ViewMode="Details" />
        <UploadPane ViewMode="List">
        </UploadPane>
        <DetailsViewColumns DimensionsText="" InfoText="" />
        <PaneItem ShowFileNameInThumbnailsView="true" />
        <UploadSettings FilesPerPackage="1" />
    </aurja:Uploader>
    <% } %>
</asp:Content>

It is important to use a separate ImageUploaderFlash.UploadRequest control instead of specifying BaseUploadControl.FileUploaded event handler for each control - otherwise you will have to dublicate your implementation.

See Also

Reference

Manual