Maintain order of selected files in FileUpload with AllowMultiple=true

1.9k views Asked by At

I have an <asp:FileUpload> control with the property AllowMultiple set to true:

<asp:fileupload id="FileUpload" runat="server" allowmultiple="true" cssclass="fileUpload btn btn-sm btn-default" onchange="preloadImages()" />

<div class="field col-md-2 col-md-offset-1 immScarpePreview MainPreviewBox">
 <asp:image id="Image1" runat="server" visible="false" cssclass="img-responsive" />
 <asp:button id="ImmButton" runat="server" text="Upload" onclick="ImmButton_Click" cssclass="hidden" />
</div>

In my JavaScript function, I simulate a click on the invisible button:

<script>
    function preloadImages() {
        $('#<%=ImmButton.ClientID%>').trigger('click');
    }
</script>

In the code-behind, I save the files to a temporary folder, and I display the uploaded images in the <asp:Image> controls:

 protected void ImmButton_Click(object sender, EventArgs e)
 {
        if (FileUpload.HasFile)
        {
            try
            {
                int cont = 0;
                byte[] fileData = null;
                foreach (HttpPostedFile file in FileUpload.PostedFiles)
                {
                    if (cont == 0)
                    {
                        using (var binaryReader = new BinaryReader(file.InputStream))
                            fileData = binaryReader.ReadBytes(file.ContentLength);
                        File.WriteAllBytes(Server.MapPath("immScarpe/tmp/" + file.FileName), fileData);
                        setImage1("immScarpe/tmp/" + file.FileName);
                    }
                    else if (cont == 1)
                    {
                        using (var binaryReader = new BinaryReader(file.InputStream))
                            fileData = binaryReader.ReadBytes(file.ContentLength);
                        File.WriteAllBytes(Server.MapPath("immScarpe/tmp/" + file.FileName), fileData);
                        setImage2("immScarpe/tmp/" + file.FileName);
                    }
                    else if (cont == 2)
                     //and so on...

                    //so on...
                    cont++;
                }
            }
            catch(Exception ex)
            {
                //error writing file
                Console.Write(ex.Message);
            }
        }
 }

 private void setImage1(string image) //all equals for all the 5 images
 {
     Image1.ImageUrl = image;
     Image1.Visible = true;
 }

This is working perfectly but I need some help. When I loop through FileUpload.PostedFiles, the order of the selected images is alphabetical I think. I would like to keep the order of the user's selection. Is this possible?

1

There are 1 answers

0
Michael Liu On BEST ANSWER

I have bad news, at least if you’re using Windows.

I tested your code using Chrome, Edge, Firefox, and Internet Explorer on Windows 10, and I inspected the HTTP POST requests using Telerik Fiddler. I got identical results in all browsers:

  • The order of files in the FileUpload.PostedFiles collection is the same as in the HTTP request; ASP.NET doesn’t sort the files in the collection.
  • The order of files in the HTTP request is the same as in the upload control; the browser doesn’t sort the files in the HTTP request. (To see the files in the upload control, I disabled your preloadImages function.)
  • The order of files in the upload control (as well as in the client-side files collection) is not necessarily the same as in the File name box in the Windows file selection dialog:
    • If I manually type the names of files out of order, then the upload control lists the files in the order in which I typed them, and the FileUpload.PostedFiles collection maintains that order.
    • However, if I select files out of order by Ctrl+clicking them, then the upload control lists the files alphabetically, as does the FileUpload.PostedFiles collection.

In that final case, I assume Windows sorts the files before giving them to the browser. If that’s true, then the browser never receives the original order of the user's selection, and so you can’t maintain the order, not even with JavaScript.

If you absolutely must maintain the order of multiple uploaded files, then you probably need to have multiple <asp:FileUpload> controls each with AllowMultiple="False".