In this article I will explain with an example and attached sample code, how to download multiple files at once in one HTTP Request in ASP.Net using C# and VB.Net.
HTTP Response does not allow multiple files to be downloaded and hence the solution is to compress and zip multiple files into a single Zip Archive file using the DotNetZip Library in ASP.Net using C# and VB.Net.
Referencing the DotNetZip Library
You will need to download the DotNetZip Library DLL using the Download Link provided below.
Download DotNetZip Or your will find the DLL in the attached sample at the end of the article.
Once you have the DLL you need to place the Ionic.Zip.Reduced.dll in the BIN Folder.
Namespaces
You will need to import the following Namespaces.
C#
using System.IO;
using Ionic.Zip;
using System.Collections.Generic;
VB.Net
Imports System.IO
Imports Ionic.Zip
Imports System.Collections.Generic
Storage of Files on Server Directory
In my website I have created a Folder named Files which contains the following files as shown in the screenshot below.
Displaying the Files stored in Folder on the Server in ASP.Net GridView
I have placed an ASP.Net GridView control on my Web Page along with a Button that will be used to download the Files.
You will notice that I have placed a CheckBox Control in the GridView, this CheckBox will allow users to select the file that wish to download.
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" EmptyDataText="No files available">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="chkSelect" runat="server" />
<asp:Label ID="lblFilePath" runat="server" Text='<%# Eval("Value") %>' Visible="false"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Text" HeaderText="File Name" />
</Columns>
</asp:GridView>
<br />
<asp:Button ID="btnDownload" runat="server" Text="Download" OnClick="DownloadFiles" />
The following code is used to bind the List of Files from the Server Folder or Directory to the ASP.Net GridView control.
C#
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
string[] filePaths = Directory.GetFiles(Server.MapPath("~/Files/"));
List<ListItem> files = new List<ListItem>();
foreach (string filePath in filePaths)
{
files.Add(new ListItem(Path.GetFileName(filePath), filePath));
}
GridView1.DataSource = files;
GridView1.DataBind();
}
}
VB.Net
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
If Not IsPostBack Then
Dim filePaths As String() = Directory.GetFiles(Server.MapPath("~/Files/"))
Dim files As New List(Of ListItem)()
For Each filePath As String In filePaths
files.Add(New ListItem(Path.GetFileName(filePath), filePath))
Next
GridView1.DataSource = files
GridView1.DataBind()
End If
End Sub
Downloading Multiple Files selected in GridView as Zip Archive File using DotNetZip
When the Download Button is clicked, first an object of the DotNetZip Library is created and a loop is executed over the GridView rows and the all the files for which the Checkbox is checked are added to the Zip object.
Finally the Zip object is downloaded as Zip file.
C#
protected void DownloadFiles(object sender, EventArgs e)
{
using (ZipFile zip = new ZipFile())
{
zip.AlternateEncodingUsage = ZipOption.AsNecessary;
zip.AddDirectoryByName("Files");
foreach (GridViewRow row in GridView1.Rows)
{
if ((row.FindControl("chkSelect") as CheckBox).Checked)
{
string filePath = (row.FindControl("lblFilePath") as Label).Text;
zip.AddFile(filePath, "Files");
}
}
Response.Clear();
Response.BufferOutput = false;
string zipName = String.Format("Zip_{0}.zip", DateTime.Now.ToString("yyyy-MMM-dd-HHmmss"));
Response.ContentType = "application/zip";
Response.AddHeader("content-disposition", "attachment; filename=" + zipName);
zip.Save(Response.OutputStream);
Response.End();
}
}
VB.Net
Protected Sub DownloadFiles(sender As Object, e As EventArgs)
Using zip As New ZipFile()
zip.AlternateEncodingUsage = ZipOption.AsNecessary
zip.AddDirectoryByName("Files")
For Each row As GridViewRow In GridView1.Rows
If TryCast(row.FindControl("chkSelect"), CheckBox).Checked Then
Dim filePath As String = TryCast(row.FindControl("lblFilePath"), Label).Text
zip.AddFile(filePath, "Files")
End If
Next
Response.Clear()
Response.BufferOutput = False
Dim zipName As String = [String].Format("Zip_{0}.zip", DateTime.Now.ToString("yyyy-MMM-dd-HHmmss"))
Response.ContentType = "application/zip"
Response.AddHeader("content-disposition", "attachment; filename=" + zipName)
zip.Save(Response.OutputStream)
Response.End()
End Using
End Sub
Screenshot
Demo
Downloads