Answered by:
How to open file downloaded from database in new browser window

Question
-
User-105508883 posted
Hi,
please I have this function in my ASP webforms which is download file from database when I click on Download text. Please how to modify it to directly open that file in new browser window or tab?
ASP page
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="LLPIposAttachment.Default" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>iPOS Attachment</title> </head> <body> <form id="form1" runat="server"> <div> <h2>iPOS Attachments List</h2> </div> <asp:GridView ID="AttachmentList" runat="server" AutoGenerateColumns="false"> <Columns> <asp:BoundField DataField="ATTACH_NAME" HeaderText="File Name" /> <asp:TemplateField ItemStyle-HorizontalAlign="Center"> <ItemTemplate> <asp:LinkButton ID="lnkDownload" runat="server" Text="Download" OnClick="DownloadFile" CommandArgument='<%# Eval("ATTACH_ID") %>'></asp:LinkButton> </ItemTemplate> </asp:TemplateField> </Columns> </asp:GridView> </form> </body> </html>
C# code behind
using System; using System.Collections.Generic; using System.Data.SqlClient; using System.Linq; using System.Web; using System.Web.Configuration; using System.Web.UI; using System.Web.UI.WebControls; namespace LLPIposAttachment { public partial class Default : System.Web.UI.Page { SqlConnection sqlCon; string bu; string jn; protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { if (Request.QueryString["BU"] != null) { bu = Request.QueryString["BU"].ToString(); } if (Request.QueryString["JN"] != null) { jn = Request.QueryString["JN"].ToString(); } BindGrid(); } } private void BindGrid() { sqlCon = new SqlConnection(WebConfigurationManager.AppSettings["inputSqlCon"]); sqlCon.Open(); string inputSql = @"SELECT atta.ATTACH_ID, atta.ATTACH_NAME FROM PA_REQ_NOTE_ATTACHMENTS atta join PA_REQ_INVOICES inv on atta.NOTE_ID = inv.NOTE join PK1_A_SALFLDG ldg on ldg.TREFERENCE = 'IP ' + CONVERT(varchar(12), INV_NO) where inv.SUN_DB = '" + bu + "' and D_C = 'C' and ldg.JRNAL_NO = " + jn; SqlCommand sqCom = new SqlCommand(inputSql, sqlCon); SqlDataReader sqRead = sqCom.ExecuteReader(); AttachmentList.DataSource = sqRead; AttachmentList.DataBind(); sqlCon.Close(); } protected void DownloadFile(object sender, EventArgs e) { string id = (sender as LinkButton).CommandArgument; byte[] bytes; string fileName; //string contentType; string constr = WebConfigurationManager.AppSettings["inputSqlCon"]; using (SqlConnection con = new SqlConnection(constr)) { using (SqlCommand cmd = new SqlCommand()) { cmd.CommandText = @"SELECT ATTACH_NAME, ATTACH FROM PA_REQ_NOTE_ATTACHMENTS where ATTACH_ID = @Id"; cmd.Parameters.AddWithValue("@Id", id); cmd.Connection = con; con.Open(); using (SqlDataReader sdr = cmd.ExecuteReader()) { sdr.Read(); bytes = (byte[])sdr["ATTACH"]; //contentType = sdr["ContentType"].ToString(); fileName = sdr["ATTACH_NAME"].ToString(); } con.Close(); } } Response.Clear(); Response.Buffer = true; Response.Charset = ""; Response.Cache.SetCacheability(HttpCacheability.NoCache); string mimeType = MimeMapping.GetMimeMapping(fileName); Response.ContentType = mimeType; Response.AppendHeader("Content-Disposition", "attachment; filename=" + fileName); Response.BinaryWrite(bytes); Response.Flush(); Response.End(); } } }
Tuesday, May 25, 2021 1:56 PM
Answers
-
User-1330468790 posted
Hi pavlli,
Actually you don't need this method as it is just used to make an example to show how to pass a file to client.
You already have your own implementation, which is implemented with
Response.BinaryWrite(bytes);
Response.BinaryWrite(bytes) and Response.TransmitFile(Server.MapPath(fileName)) here are doing the similar thing => Write file to the response.
However, "Response.BinaryWrite(bytes)" writes a string of binary characters to the HTTP output stream but "Response.TransmitFile(Server.MapPath(fileName))" writes the specified file directly to an HTTP response output stream, without buffering it in memory.
More details, you can refer to the documentation: HttpResponse.TransmitFile Method and HttpResponse.BinaryWrite(Byte[]) Method.
Best regards,
Sean
- Marked as answer by An0nym0u5User Tuesday, June 22, 2021 12:00 AM
Thursday, May 27, 2021 2:43 AM
All replies
-
User-1545767719 postedPlease how to modify it to directly open that file in new browser window or tab?
Don't consider "download" to do so. Prepare a separate page which shows the result of "click" and request it by using javascript.
Tuesday, May 25, 2021 11:09 PM -
User-1330468790 posted
Hi pavlli,
please I have this function in my ASP webforms which is download file from database when I click on Download text. Please how to modify it to directly open that file in new browser window or tab?If you want to open the file instead of downloading the file directly, you need to modify the header from "attachment" to "inline".
For example, headers to open a pdf file:
Content-Type: application/pdf Content-Disposition: inline; filename="filename.pdf"
In your codes, it would be :
string mimeType = MimeMapping.GetMimeMapping(fileName); Response.ContentType = mimeType; Response.AppendHeader("Content-Disposition", "inline; filename=" + fileName); Response.BinaryWrite(bytes); Response.Flush(); Response.End();
If you want to open the file in a new browser or tab, the best way is to open a new page and get the file from that page.
For example,
<a href="viewpdf.aspx" target="_blank">View PDF</a>
Hope helps.
Best regards,
Sean
Wednesday, May 26, 2021 5:22 AM -
User-105508883 posted
Hi Sean,
thanks for your answer. I am really new to ASP webs, so I sorry for dumb questions. I understand the C# part, but how to connect it to the browser part ? So that after mouse click, it will open new browser window with my file?
<a href="viewpdf.aspx" target="_blank">View PDF</a>
I suppose, that I have modify my Download text, put the above html to CommandArgument part somehow?
<asp:LinkButton ID="lnkDownload" runat="server" Text="Download" OnClick="DownloadFile" CommandArgument='<%# Eval("ATTACH_ID") %>'></asp:LinkButton>
Wednesday, May 26, 2021 6:52 AM -
User-1330468790 posted
Hi pavlli,
Everyone starts from knowing nothing, no worries.
What I mean is to open a new tab with another page and let this page to provide a download/view functionality.
You can refer to below codes which uses LinkButton and another aspx page to provide file viewing function. However, you can directly bind "ATTACH_ID" to <a> tags.
DownloadPDF.aspx
<form id="form1" runat="server"> <div> <asp:LinkButton ID="lnkDownload" runat="server" Text="Download"></asp:LinkButton> </div> </form>
DownloadPDF.aspx.cs
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { // You can add ATTACH_ID as a query string and this ID can be bound in databind event lnkDownload.Attributes.Add("href", "./GetPDF.aspx"); lnkDownload.Attributes.Add("target", "_blank"); } }
GetPDF.aspx:
<form id="form1" runat="server"> <div> <!-- No need to add anything --> </div> </form>
GetPDF.aspx.cs:
protected void Page_Load(object sender, EventArgs e) { string fileName = "321.pdf"; Response.Clear(); Response.Buffer = true; Response.Charset = ""; Response.Cache.SetCacheability(HttpCacheability.NoCache); Response.ContentType = "Application/pdf"; Response.AppendHeader("Content-Disposition", "inline; filename=" + fileName); Response.TransmitFile(Server.MapPath("/uploads/321.pdf")); Response.Flush(); Response.End(); }
You can run this simple demo from your side and result would be
- A new tab will be opened after click the linkbutton with url "GetPDF.aspx"
- the file "321.pdf" will be viewed in this new tab
Alternatively, you can implement a handler to be responsible for viewing/downloading files.
https://stackoverflow.com/questions/10912164/what-is-the-best-way-to-download-file-from-server
Best regards,
Sean
Wednesday, May 26, 2021 8:22 AM -
User-105508883 posted
Really thanks for you help Sean. My updated code is now this:
Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="LLPIposAttachment.Default" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>iPOS Attachment</title> </head> <body> <form id="form1" runat="server"> <div> <h2>iPOS Attachments List</h2> </div> <asp:GridView ID="AttachmentList" runat="server" AutoGenerateColumns="false"> <Columns> <asp:BoundField DataField="ATTACH_NAME" HeaderText="File Name" /> <asp:TemplateField ItemStyle-HorizontalAlign="Center"> <ItemTemplate> <asp:LinkButton ID="lnkDownload" runat="server" Text="Download" OnClick="DownloadFile" CommandArgument='<%# Eval("ATTACH_ID") %>'></asp:LinkButton> </ItemTemplate> </asp:TemplateField> </Columns> </asp:GridView> </form> </body> </html>
Default.aspx.cs
using System; using System.Collections.Generic; using System.Data.SqlClient; using System.Linq; using System.Web; using System.Web.Configuration; using System.Web.UI; using System.Web.UI.WebControls; namespace LLPIposAttachment { public partial class Default : System.Web.UI.Page { SqlConnection sqlCon; string bu; string jn; protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { if (Request.QueryString["BU"] != null) { bu = Request.QueryString["BU"].ToString(); } if (Request.QueryString["JN"] != null) { jn = Request.QueryString["JN"].ToString(); } BindGrid(); } } private void BindGrid() { sqlCon = new SqlConnection(WebConfigurationManager.AppSettings["inputSqlCon"]); sqlCon.Open(); string inputSql = @"SELECT atta.ATTACH_ID, atta.ATTACH_NAME FROM PA_REQ_NOTE_ATTACHMENTS atta join PA_REQ_INVOICES inv on atta.NOTE_ID = inv.NOTE join PK1_A_SALFLDG ldg on ldg.TREFERENCE = 'IP ' + CONVERT(varchar(12), INV_NO) where inv.SUN_DB = '" + bu + "' and D_C = 'C' and ldg.JRNAL_NO = " + jn; SqlCommand sqCom = new SqlCommand(inputSql, sqlCon); SqlDataReader sqRead = sqCom.ExecuteReader(); AttachmentList.DataSource = sqRead; AttachmentList.DataBind(); sqlCon.Close(); } protected void DownloadFile(object sender, EventArgs e) { string id = (sender as LinkButton).CommandArgument; (sender as LinkButton).Attributes.Add("href", "./GetFile.aspx"); (sender as LinkButton).Attributes.Add("target", "_blank"); Response.Redirect("./GetFile.aspx?ID=" + id); } } }
GetFile.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="GetFile.aspx.cs" Inherits="LLPIposAttachment.GetFile" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> </head> <body> <form id="form1" runat="server"> <div> </div> </form> </body> </html>
GetFile.aspx.cs
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Data.SqlClient; using System.Web.Configuration; namespace LLPIposAttachment { public partial class GetFile : System.Web.UI.Page { string id; protected void Page_Load(object sender, EventArgs e) { id = Request.QueryString["ID"]; GetF(); } private void GetF() { byte[] bytes; string fileName; string mimeType; string constr = WebConfigurationManager.AppSettings["inputSqlCon"]; using (SqlConnection con = new SqlConnection(constr)) { using (SqlCommand cmd = new SqlCommand()) { cmd.CommandText = @"SELECT ATTACH_NAME, ATTACH FROM PA_REQ_NOTE_ATTACHMENTS where ATTACH_ID = @Id"; cmd.Parameters.AddWithValue("@Id", id); cmd.Connection = con; con.Open(); using (SqlDataReader sdr = cmd.ExecuteReader()) { sdr.Read(); bytes = (byte[])sdr["ATTACH"]; fileName = sdr["ATTACH_NAME"].ToString(); } con.Close(); } } Response.Clear(); Response.Buffer = true; Response.Charset = ""; Response.Cache.SetCacheability(HttpCacheability.NoCache); mimeType = MimeMapping.GetMimeMapping(fileName); Response.ContentType = mimeType; Response.AppendHeader("Content-Disposition", "inline; attachment; filename=" + fileName); //Response.AppendHeader("Content-Disposition", "attachment; filename=" + fileName); Response.TransmitFile(Server.MapPath(fileName)); Response.BinaryWrite(bytes); Response.Flush(); Response.End(); } } }
I succesfully pass ATTACH_ID parameter to GetFile page, so I can download file from database. But I don't undestand this part:
Response.TransmitFile(Server.MapPath(fileName));
I am trying to use fileName variable here, because files stored in database which I need to download can be PDF or images. I suppose in this part file should be downloaded, saved, and finally displayed on GetFile page?
But i receive this error, so file isn't downloaded, or it's saved somewhere else?
System.IO.FileNotFoundException: 'Could not find file 'C:\VYVOJ2\SmallDev\LLPIposAttachment\LLPIposAttachment\IPOS_logo11.gif'.'
And again, really thanks for you help here.
Wednesday, May 26, 2021 11:18 AM -
User-1330468790 posted
Hi pavlli,
Actually you don't need this method as it is just used to make an example to show how to pass a file to client.
You already have your own implementation, which is implemented with
Response.BinaryWrite(bytes);
Response.BinaryWrite(bytes) and Response.TransmitFile(Server.MapPath(fileName)) here are doing the similar thing => Write file to the response.
However, "Response.BinaryWrite(bytes)" writes a string of binary characters to the HTTP output stream but "Response.TransmitFile(Server.MapPath(fileName))" writes the specified file directly to an HTTP response output stream, without buffering it in memory.
More details, you can refer to the documentation: HttpResponse.TransmitFile Method and HttpResponse.BinaryWrite(Byte[]) Method.
Best regards,
Sean
- Marked as answer by An0nym0u5User Tuesday, June 22, 2021 12:00 AM
Thursday, May 27, 2021 2:43 AM