Thursday, September 22, 2011

Upload Multiple Files in ASP.NET


The concept is as follows:
One FileUpload control on the page
One DataList to show which images the user will be uploading
Store image information in a dataset with one of the columns being the image in bytes
User has option to remove image from the upload list if they want before uploading it.

getImage.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
 //TODO: error checking for query string
 if(Session["dsPhotoFiles"] != null)
 {
      DataSet tmpDs = new DataSet();
      tmpDs = (DataSet)Session["dsPhotoFiles"];
      for (int i = 0; i < tmpDs.Tables[0].Rows.Count; i++)
      {
         if (tmpDs.Tables[0].Rows[i]["id"].ToString() == Request.QueryString["id"])
         {
             Response.BinaryWrite((byte[])(tmpDs.Tables[0].Rows[i]["fileBytes"]));
             break;
         }
      }
 }
}

Below is now the code for the main page used to upload multiple images.
Default.aspx
This is the code inside the form tag
<div>
     <asp:Label ID="Label1" runat="server" Text="Locate File:" />&nbsp;&nbsp;
     <asp:FileUpload ID="fileUp" runat="server" /> &nbsp;&nbsp;
     <br />
     <asp:Label ID="Description" runat="server" Text="Description:"></asp:Label>&nbsp;&nbsp;
     <asp:TextBox ID="txtDesc" runat="server" Width="349px"></asp:TextBox>
     <asp:Button ID="btnAddFile" runat="server" Text="Add File To Upload List" 
                onclick="btnAddFile_Click" />
</div>
  
<div>
     <asp:Label ID="lblCurrentFileCount" runat="server"></asp:Label>
     <br />
     <asp:DataList ID="dlPhotoFiles" runat="server" RepeatColumns="10" RepeatDirection="Horizontal">
         <ItemTemplate>
             <asp:Image ID="Image1" runat="server" ImageUrl='<%# string.Format("~/getImage.aspx?id={0}", Eval("id")) %>' 
                   Width="50" AlternateText='<%# Eval("fileDesc") %>' />
             <br />
             <asp:LinkButton ID="lnkBtnRemovePhoto" runat="server" 
                        CommandArgument='<%# Eval("id") %>' OnCommand="lnkBtnRemovePhoto_Command">Remove</asp:LinkButton>
         </ItemTemplate>                   
      </asp:DataList>
      <br />
</div>
<br />
<div>
     <asp:Button ID="btnUploadFiles" runat="server" Text="Upload File(s)" 
                   onclick="btnUploadFiles_Click" />
</div>

Default.aspx.cs
This is all of the code behind:
DataSet dsPhotosFiles = new DataSet();
        protected void Page_Init(object sender, EventArgs e)
        {
            if (Session["dsPhotoFiles"] == null)
            {
                this.initPhotoDS();
                Session.Add("dsPhotoFiles", dsPhotosFiles);
            }
            else
            {
                dsPhotosFiles = (DataSet)Session["dsPhotoFiles"];
            } 
        }
        protected void btnAddFile_Click(object sender, EventArgs e)
        {
            if (fileUp.PostedFile.ContentLength > 0)
            {
                //TODO: logic for file extension check
                DataRow dr = dsPhotosFiles.Tables[0].NewRow();
                string fileExt = System.IO.Path.GetExtension(fileUp.PostedFile.FileName);
                byte[] imageBytes = new byte[fileUp.PostedFile.InputStream.Length];
                fileUp.PostedFile.InputStream.Read(imageBytes, 0, imageBytes.Length);
                dr["fileBytes"] = imageBytes;
                dr["filePath"] = fileUp.PostedFile.FileName;
                dr["fileDesc"] = txtDesc.Text;
                dr["id"] = System.Guid.NewGuid().ToString();
                dsPhotosFiles.Tables[0].Rows.Add(dr);
            }
            this.bindDataList();          
            txtDesc.Text = "";
            lblCurrentFileCount.Text = "Current Files To Upload: " + dsPhotosFiles.Tables[0].Rows.Count;
        }
        protected void btnUploadFiles_Click(object sender, EventArgs e)
        {
            try
            {
                for (int i = 0; i < dsPhotosFiles.Tables[0].Rows.Count; i++)
                {
                    //TODO:logic to save image path and description to database
                    
                    string fileName = System.IO.Path.GetFileName(dsPhotosFiles.Tables[0].Rows[i]["filePath"].ToString());
                    byte[] imageBytes;
                    imageBytes = (byte[])dsPhotosFiles.Tables[0].Rows[i]["fileBytes"];
                    //their is no uploading..just writing out the bytes to the directory on the web server.
                    System.IO.File.WriteAllBytes(Server.MapPath(string.Format("~/documents/{0}", fileName)), imageBytes);
                }
                //TODO: show success message logic
                //clear out rows of dataset not the whole dataset
                dsPhotosFiles.Tables[0].Rows.Clear();
                this.bindDataList();
                lblCurrentFileCount.Text = "Current Files To Upload: " + "0";
                
            }
            catch (Exception ex)
            {
                //TODO: show error message of which file did not get uploaded
                throw new Exception(ex.Message);
            }
           
        }
        private void initPhotoDS()
        {
            dsPhotosFiles.Tables.Add("Photos");
            dsPhotosFiles.Tables[0].Columns.Add("fileBytes", Type.GetType("System.Byte[]"));
            dsPhotosFiles.Tables[0].Columns.Add("filePath");
            dsPhotosFiles.Tables[0].Columns.Add("fileDesc");
            dsPhotosFiles.Tables[0].Columns.Add("id");
        }
        private void bindDataList()
        {
            dlPhotoFiles.DataSource = dsPhotosFiles;
            dlPhotoFiles.DataKeyField = "id";
            dlPhotoFiles.DataBind();
        }
        protected void lnkBtnRemovePhoto_Command(object sender, CommandEventArgs e)
        {
            foreach(DataRow dr in dsPhotosFiles.Tables[0].Rows)
            {
                if (dr["id"].ToString() == e.CommandArgument.ToString())
                {
                    dsPhotosFiles.Tables[0].Rows.Remove(dr);
                    break;
                }
            }
            this.bindDataList();
            lblCurrentFileCount.Text = "Current Files To Upload: " + dsPhotosFiles.Tables[0].Rows.Count;
        }

The image is in memory so their really isn’t any uploading involved because once it’s in memory it’s write it directly to the directy on the web server.
Gives the user the ability to see the photos they are uploading
Gives the user the ability to remove photos before they commit to uploading them
Can write image information to a database if you would like.

No comments :

Post a Comment