File Download with save as dialog box from browser


Every programmer will get into this scenario where they needs to download a file from browser with a direct button click or downloading a file after some business functional process.

Scenario1:  Downloading a file with a button click.

To achieve this
  1. File has to be saved to hard drive on server 

  2. Create a link button and write the following code at the <button>_Click event.(Replace your filename with location at "<filename>")

    System.IO.FileStream fs = null;
    fs = System.IO.File.Open(<filename>,FileMode.Open);
    byte[] btFile = new byte[fs.Length];
    fs.Read(btFile, 0, Convert.ToInt32(fs.Length));
    fs.Close();
    Response.Buffer = true;
    Response.Expires = 0;
    Response.ContentType = "plain/text";
    Response.AddHeader("Content-Type", "plain/text");
    //Response.AddHeader("Content-Length", btFile.Length.ToString);
    Response.AddHeader("Content-Disposition", "attachment;filename=" +    Session["downloadFname"].ToString());
    Response.Cache.SetCacheability(HttpCacheability.NoCache);
    Response.BinaryWrite(btFile);
    Response.End();
Scenario 2: Downloading a file after some business functional process.

Most of the time this could be, you click a button and that button click will execute a function or some process with generates some results . These results have to be downloaded as file.

In this case I'm providing code for generating a tab delimited text file from the data table. And then downloading that file using save as dialog box from the browser with no user interaction.

Generate tab delimited text file from a data table: ( Replace with you filename including path)

StreamWriter sw = new StreamWriter(<filename including path>, false);
int iColCount = dt.Columns.Count;
for (int i = 0; i < iColCount; i++)
{
    sw.Write(dt.Columns[i]);
    if (i < iColCount - 1)
    {
        sw.Write("\t");
    }
}
sw.Write(sw.NewLine);
foreach (DataRow dr in dt.Rows)
{
    for (int i = 0; i < iColCount; i++)
    {
        sw.Write(dr[i].ToString().Trim());
        if (i < iColCount - 1)
        {
            sw.Write("\t");
        }
    }
    sw.Write(sw.NewLine);
}
sw.Close();

Downloading file: Here I'm providing multiple of ways of doing the same thing. Please use which ever you are comfortable with.

  1. byte[] fileC = File.ReadAllBytes(<filename>);
    HttpContext.Current.Response.ClearContent();
    HttpContext.Current.Response.ContentType = "text/plain";
    HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment;filename="+ <filename> );
    HttpContext.Current.Response.AppendHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
    HttpContext.Current.Response.AppendHeader("Pragma", "public");
    HttpContext.Current.Response.AppendHeader("Expires", "0");
    HttpContext.Current.Response.OutputStream.Write(fileC, 0, fileC.Length);
    HttpContext.Current.Response.Flush();
    HttpContext.Current.Response.Clear();
    HttpContext.Current.Response.End();
    Response.Clear();
    Response.ClearContent();
    Response.ContentType = "text/plain";
    Response.AppendHeader("Content-Disposition", "attachment; filename="+<filename>);
    Response.TransmitFile(recapPath + fname);
    Response.Clear();
    Response.Flush();
    Response.End();

  2. Response.ContentType = "text/txt";
    Response.AppendHeader("Content-Disposition", "attachment; filename=" + <filename> + ".txt");
    Page.Response.WriteFile(<filename with extention>);
    Response.End();

  3. System.IO.FileStream fs = null;
    fs = System.IO.File.Open(<filename>, FileMode.Open);
    byte[] btFile = new byte[fs.Length];
    fs.Read(btFile, 0, Convert.ToInt32(fs.Length));
    fs.Close();
    Response.Clear();
    Response.AppendHeader("content-disposition", "attachment; filename=" + <filename>);
    Response.ContentType = "plain/text";
    UTF8Encoding encoding = new UTF8Encoding();
    Response.BinaryWrite(btFile);
    Response.Flush();
    Response.End();

  4. System.IO.FileStream fs = null;
    fs = System.IO.File.Open(<filename>, FileMode.Open);
    byte[] btFile = new byte[fs.Length];
    fs.Read(btFile, 0, Convert.ToInt32(fs.Length));
    fs.Close();
    Response.Buffer = true;
    Response.Expires = 0;
    Response.ContentType = "plain/text";
    Response.AddHeader("Content-Type", "plain/text");
    Response.AddHeader("Content-Length", btFile.Length.ToString);
    Response.AddHeader("Content-Disposition", "attachment;filename=" + <filename>);
    Response.Cache.SetCacheability(HttpCacheability.NoCache);
    Response.BinaryWrite(btFile );
    Response.End();

Please remember that the URL for the page where button exists for this functionality shouldn't be secure URL incase if you are using IE6. So, If your clients are going to use the website on IE6 and they want this functionality, make sure that URL doesn't start with  https:// . It should start with http:// because IE6 doesn't flush the file contents properly. 

Hope this article will help you to spend as little time as possible for this functionality. 


Similar Articles