Friday, June 6, 2008

Upload Multiple Files With ASP.NET

Out of the box, you can easily upload files using the ASP.NET FileUpload control. However there are times when the design calls for the ability to upload multiple files. In my example, I use a single FileUpload control along with a GridView for layout and some Session state to store the posted files. You can copy and paste the code below to accomplish this task.

Design

MultipleUpload

ASP.NET

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Untitled Page</title>
    <script language="javascript" type="text/javascript">
        function SetFileGridIndex(index)
        {
            var myControl = document.getElementById('<%= fileGridIndex.ClientID %>');
            myControl.value = index;
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div style="font-family: Verdana; font-size: small; text-align:center; width:100%;">
        <asp:GridView ID="fileGrid" AutoGenerateColumns="False" ShowFooter="true" BorderColor="Black"
            BorderWidth="1px" runat="server" OnRowCommand="fileGrid_RowCommand" GridLines="None"
            OnRowDeleting="fileGrid_RowDeleting">
            <Columns>
                <asp:BoundField DataField="Key" HeaderText="Files To Upload" />
                <asp:TemplateField ShowHeader="False">
                    <ItemTemplate>
                        <asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="False" CommandName="Delete"
                            Text="Delete" OnClientClick='<%# Eval("Key", "SetFileGridIndex(\"{0}\");") %>'></asp:LinkButton>
                    </ItemTemplate>
                    <FooterTemplate>
                        <asp:Button ID="Upload" runat="server" Text="Upload" CommandName="Upload" />
                    </FooterTemplate>
                </asp:TemplateField>
            </Columns>
        </asp:GridView>
        <asp:HiddenField ID="fileGridIndex" runat="server" />
        <div id="fileList" runat="server">
        </div>
        <asp:FileUpload ID="fileUpload" runat="server" />
        <asp:Button ID="AddFile" runat="server" Text="Add" OnClick="AddFile_Click" Height="20px" />
        <br />
    </div>
    </form>
</body>
</html>

Code Behind:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;

public partial class _Default : System.Web.UI.Page
{
    private Dictionary<string, HttpPostedFile> postedFiles;
    public Dictionary<string, HttpPostedFile> PostedFiles
    {
        get
        {
            return ((Dictionary<string, HttpPostedFile>)Session["PostedFiles"]);
        }
        set
        {
            Session["PostedFiles"] = value;
            postedFiles = value;
        }
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            Session["PostedFiles"] = new Dictionary<string, HttpPostedFile>();
        }
    }

    public void LoadData()
    {
        fileGrid.DataSource = PostedFiles;
        fileGrid.DataBind();
    }

    protected void AddFile_Click(object sender, EventArgs e)
    {
        if (!PostedFiles.ContainsKey(Path.GetFileName(fileUpload.PostedFile.FileName)))
        {
            PostedFiles.Add(Path.GetFileName(fileUpload.PostedFile.FileName), fileUpload.PostedFile);
            LoadData();
        }
    }

    protected void fileGrid_RowCommand(object sender, GridViewCommandEventArgs e)
    {
        switch (e.CommandName)
        {
            case "Delete":
                string fileName = fileGridIndex.Value;
                PostedFiles.Remove(fileName);
                LoadData();
                break;
            case "Upload":
                foreach (HttpPostedFile postedFile in PostedFiles.Values)
                {
                    postedFile.SaveAs(@"c:\\temp\" + Path.GetFileName(postedFile.FileName));    //CHANGE ME
                }
                PostedFiles = new Dictionary<string, HttpPostedFile>();
                LoadData();
                break;
        }
    }
    protected void fileGrid_RowDeleting(object sender, GridViewDeleteEventArgs e)
    {

    }
}

1 comment:

  1. Hi,

    I got error here: BC32017: Comma, ')', or a valid expression continuation expected.

    -->

    so i changed to :
    SetFileGridIndex(""{0}"");


    then i got another error - System.Web.HttpException: The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>).

    Any idea why? Thanks in advance

    ReplyDelete