Downloading a file from web server to client (web browser) is a very common requirement in a web application or website. Following approaches can be used to achieve it using ASP.Net and C#:

1) If file is in the same web server where web application or website is running:

a) You can just add a link to the file to be downloaded. Use following code in your ASP.Net page:

<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="~/Downloads/Sample.zip">Download</asp:HyperLink> 
OR
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="http://www.SiteName.com/Downloads/Sample.zip">Download</asp:HyperLink>

When user click on the link, either file will be opened directly in the web browser (if the plug-in for the downloaded file is installed) or user will be prompted to Open/Save the file. But I felt this approach is a static method and aslo not very secure.

b) The second approach to do this is a dynamic method i.e. programmatically downloading a file from web server to client. First add a LinkButton in your Asp.Net page, use following code snippet:

<asp:LinkButton ID="_lbtDownload " runat="server" OnClick="_lbtDownload _Click">Download</asp:LinkButton>

Now go to code behid file of the ASP.Net page and write following C# code in the Click event of the LinkButton:

protected void _lbtDownload_Click(object sender, EventArgs e)
{
  HttpWebRequest objRequest = (HttpWebRequest)WebRequest.Create("http://www.SiteName.com/Downloads/Sample.zip");
  HttpWebResponse objResponse = (HttpWebResponse)objRequest.GetResponse();
  int bufferSize = 1;
  Response.Clear();
  Response.ClearHeaders();
  Response.ClearContent();
  Response.AppendHeader("Content-Disposition:", "attachment; filename=Sample.zip");
  Response.AppendHeader("Content-Length", objResponse.ContentLength.ToString());
  Response.ContentType = "application/download";
  byte[] byteBuffer = new byte[bufferSize + 1];
  MemoryStream memStrm = new MemoryStream(byteBuffer, true);
  Stream strm = objRequest.GetResponse().GetResponseStream();
  byte[] bytes = new byte[bufferSize + 1];
  while (strm.Read(byteBuffer, 0, byteBuffer.Length) > 0)
  {
    Response.BinaryWrite(memStrm.ToArray());
    Response.Flush();
  }
  Response.Close();
  Response.End();
  memStrm.Close();
  memStrm.Dispose();
  strm.Dispose();
}

When user will click on LinkButton, above code will be executed which will download the “Sample.zip” file to the user’s computer.

2) If file is in the remote file server: In this case, the same code as in above section 1(a) can be used with little modifications. First add a LinkButton in your Asp.Net page, use following code snippet:

<asp:LinkButton ID="_lbtDownload" runat="server" OnClick="_lbtDownload _Click">Download</asp:LinkButton>

Now again go to code behid file of the ASP.Net page and write following C# code in the Click event of the LinkButton:

protected void _lbtDownload_Click(object sender, EventArgs e)
{
  FileInfo file = new FileInfo(@"\\RemoteServerIP_OR_Name\FolderName\Sample.zip");
  Response.Clear();
  Response.ClearHeaders();
  Response.ClearContent();
  Response.AppendHeader("Content-Disposition", "attachment; filename = Sample.zip");
  Response.AppendHeader("Content-Length", file.Length.ToString());
  Response.ContentType = "application/download";
  Response.WriteFile(file.FullName);
  Response.Flush();
  Response.Close();
  Response.End();
}

Note: Please make sure that the user ID under which your web application or website is running must have atleast read access to the remote file server.

Updates (March 3, 2009)
Some days after implmenting above code, I noticed an issue. While downloading of file is working fine, but after downloading the file, postback on the page stops working until the page is refreshed i.e. after downloading file, whatever you do on the page like click on a button, or click on download link again, etc., nothing will happen in the page and the page starts working only when you refresh the page.

But this issue can be resolved. To find solution visit No postback after downloading file in asp.net web application