从数据库下载同一记录中的多个文件 table
Download multiple files in same record from a database table
我有这个 table 来存储采购订单数据,它最多可以容纳 3 个文件(第一个文件是必需的,第二个和第三个是可选的),它们的列名称在图片中突出显示。
我已经完成了上传页面,它将用户输入和上传的所有数据保存到数据库中,它工作正常,我可以在 table 中看到所有保存的文件名和字节。
我正在处理“查看”页面,该页面从数据库中检索数据并将其显示到网页上,检索文件时遇到问题。
想法是在页面上显示文件名(工作正常),当用户点击文件名时,他们可以将其保存到计算机(或 open/run 等取决于网络浏览器提示windows),这里的问题是:我只能保存第一个文件,点击第二个和第三个文件名时,虽然在调试模式下它们(文件 2 和文件 3 的名称、类型和数据)确实存在,但没有出现 windows 保存文件的提示
,但什么也没发生
知道如何解决这个问题,或者如果有人有更好的下载这些文件的方法,请帮忙。
这是我的代码(请忽略不相关的代码,或者如果您想知道它们的作用,请告诉我):
View.aspx显示文件名
<asp:LinkButton ID="lbtPOFile" runat="server" OnClick="lbtPOFile_Click"></asp:LinkButton>
<asp:LinkButton ID="lbtPOFile2" runat="server" OnClick="lbtPOFile2_Click"></asp:LinkButton>
<asp:LinkButton ID="lbtPOFile3" runat="server" OnClick="lbtPOFile3_Click"></asp:LinkButton>
C#背后:DownloadFile()方法有3个参数,它们只是数据库中的列名table,对应file1,file2或file3,它假设用户点击时检索文件文件名(在下面的点击事件中调用)
protected void DownloadFile(string fileNameColumn, string fileTypeColumn, string fileDataColumn)
{
string guid = !string.IsNullOrEmpty(Request.QueryString["guid"]) ? Request.QueryString["guid"] : Guid.Empty.ToString();
string id = !string.IsNullOrEmpty(Request.QueryString["id"]) ? Request.QueryString["id"] : "0";
if (requestDAL.ValidatePODetailLink(guid, Convert.ToInt32(id)))
{
byte[] bytes = null;
string fileName = "";
string contentType = "";
DataTable PODetail = requestDAL.GetPODetail(guid, Convert.ToInt32(id));
foreach (DataRow row in PODetail.Rows)
{
bytes = (byte[])row[fileDataColumn];
contentType = row[fileTypeColumn].ToString();
fileName = row[fileNameColumn].ToString();
}
Response.Clear();
Response.Buffer = true;
Response.Charset = "";
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.ContentType = contentType;
Response.AppendHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
Response.BinaryWrite(bytes);
Response.Flush();
Response.End();
}
else
{
//Display message
InfoPanel.Visible = true;
lblMessage.Text = "<b>Invalid file or an error has occurred while connecting to the database. Please try again later!</b>";
lblMessage.CssClass = "text text-danger bold";
InfoPanel.CssClass = "panel panel-danger";
FormPanel.Visible = false;
FormPanel.Enabled = false;
}
}
protected void lbtPOFile_Click(object sender, EventArgs e)
{
try
{
DownloadFile("poFileName", "poFileContentType", "poFileData");
}
catch (Exception ex)
{
//Display message
InfoPanel.Visible = true;
lblMessage.Text = "<b>An error has occurred. Please try again later!</b></br>" + ex.Message;
lblMessage.CssClass = "text text-danger bold";
InfoPanel.CssClass = "panel panel-danger";
FormPanel.Visible = false;
FormPanel.Enabled = false;
}
}
protected void lbtPOFile2_Click(object sender, EventArgs e)
{
try
{
DownloadFile("poFileName2", "poFileContentType2", "poFileData2");
}
catch (Exception ex)
{
//Display message
InfoPanel.Visible = true;
lblMessage.Text = "<b>An error has occurred. Please try again later!</b></br>" + ex.Message;
lblMessage.CssClass = "text text-danger bold";
InfoPanel.CssClass = "panel panel-danger";
FormPanel.Visible = false;
FormPanel.Enabled = false;
}
}
protected void lbtPOFile3_Click(object sender, EventArgs e)
{
try
{
DownloadFile("poFileName3", "poFileContentType3", "poFileData3");
}
catch (Exception ex)
{
//Display message
InfoPanel.Visible = true;
lblMessage.Text = "<b>An error has occurred. Please try again later!</b></br>" + ex.Message;
lblMessage.CssClass = "text text-danger bold";
InfoPanel.CssClass = "panel panel-danger";
FormPanel.Visible = false;
FormPanel.Enabled = false;
}
}
一些相关的功能,以备不时之需:
// Validate link for employee (link format is View.aspx?guid=xxx&id=xxx)
public static bool ValidatePODetailLink(string guid, int poID)
{
using (SqlConnection con = new SqlConnection(CS))
{
string query = "SELECT COUNT(*) FROM PO WHERE poID = @poID AND poGUID = @guid";
SqlCommand cmd = new SqlCommand(query, con);
cmd.Parameters.AddWithValue("@guid", guid);
cmd.Parameters.AddWithValue("@poID", poID);
con.Open();
int i = Convert.ToInt32(cmd.ExecuteScalar());
if (i == 1) return true;
else return false;
}
}
//Get po request details for employee
public static DataTable GetPODetail(string guid, int poID)
{
using (SqlConnection con = new SqlConnection(CS))
{
string query = "SELECT * FROM PO WHERE poID = @poID AND poGUID = @guid";
SqlCommand cmd = new SqlCommand(query, con);
cmd.Parameters.AddWithValue("@guid", guid);
cmd.Parameters.AddWithValue("@poID", poID);
con.Open();
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
return dt;
}
}
发现问题:
我使用 UpdatePanel
并且只放置 <Triggers> <asp:PostBackTrigger ControlID="lbtPOFile" /> </Triggers>
因此它缺少 PostBackTrigger
for lbtPOFile2 和 lbtPOFile3。添加了这两行并且有效。
我建议采用以下方法。
将您的代码恢复到 "known good" 状态(它只能处理一个文件的下载,但这样做是正确的)
重构此代码,使其仍然支持单个文件下载。获取将文件内容流式传输到响应中的代码;将它移到一个单独的函数中(也许称之为 SendFile
);从您的点击处理程序调用该函数;重新编译并确认一切正常。
现在修改 SendFile
以便它接受输入参数来确定它是否 return 文件 1、文件 2 或文件 3。修改点击处理程序以便它传了文件1的参数,重新编译测试,还是可以的
现在为另外两个 link 按钮添加两个额外的点击处理程序。除了传递给 SendFile
的参数外,应该与您现有的点击处理程序相同。重新编译并测试所有三个文件。
我有这个 table 来存储采购订单数据,它最多可以容纳 3 个文件(第一个文件是必需的,第二个和第三个是可选的),它们的列名称在图片中突出显示。
我已经完成了上传页面,它将用户输入和上传的所有数据保存到数据库中,它工作正常,我可以在 table 中看到所有保存的文件名和字节。
我正在处理“查看”页面,该页面从数据库中检索数据并将其显示到网页上,检索文件时遇到问题。
想法是在页面上显示文件名(工作正常),当用户点击文件名时,他们可以将其保存到计算机(或 open/run 等取决于网络浏览器提示windows),这里的问题是:我只能保存第一个文件,点击第二个和第三个文件名时,虽然在调试模式下它们(文件 2 和文件 3 的名称、类型和数据)确实存在,但没有出现 windows 保存文件的提示
,但什么也没发生知道如何解决这个问题,或者如果有人有更好的下载这些文件的方法,请帮忙。
这是我的代码(请忽略不相关的代码,或者如果您想知道它们的作用,请告诉我):
View.aspx显示文件名
<asp:LinkButton ID="lbtPOFile" runat="server" OnClick="lbtPOFile_Click"></asp:LinkButton>
<asp:LinkButton ID="lbtPOFile2" runat="server" OnClick="lbtPOFile2_Click"></asp:LinkButton>
<asp:LinkButton ID="lbtPOFile3" runat="server" OnClick="lbtPOFile3_Click"></asp:LinkButton>
C#背后:DownloadFile()方法有3个参数,它们只是数据库中的列名table,对应file1,file2或file3,它假设用户点击时检索文件文件名(在下面的点击事件中调用)
protected void DownloadFile(string fileNameColumn, string fileTypeColumn, string fileDataColumn)
{
string guid = !string.IsNullOrEmpty(Request.QueryString["guid"]) ? Request.QueryString["guid"] : Guid.Empty.ToString();
string id = !string.IsNullOrEmpty(Request.QueryString["id"]) ? Request.QueryString["id"] : "0";
if (requestDAL.ValidatePODetailLink(guid, Convert.ToInt32(id)))
{
byte[] bytes = null;
string fileName = "";
string contentType = "";
DataTable PODetail = requestDAL.GetPODetail(guid, Convert.ToInt32(id));
foreach (DataRow row in PODetail.Rows)
{
bytes = (byte[])row[fileDataColumn];
contentType = row[fileTypeColumn].ToString();
fileName = row[fileNameColumn].ToString();
}
Response.Clear();
Response.Buffer = true;
Response.Charset = "";
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.ContentType = contentType;
Response.AppendHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
Response.BinaryWrite(bytes);
Response.Flush();
Response.End();
}
else
{
//Display message
InfoPanel.Visible = true;
lblMessage.Text = "<b>Invalid file or an error has occurred while connecting to the database. Please try again later!</b>";
lblMessage.CssClass = "text text-danger bold";
InfoPanel.CssClass = "panel panel-danger";
FormPanel.Visible = false;
FormPanel.Enabled = false;
}
}
protected void lbtPOFile_Click(object sender, EventArgs e)
{
try
{
DownloadFile("poFileName", "poFileContentType", "poFileData");
}
catch (Exception ex)
{
//Display message
InfoPanel.Visible = true;
lblMessage.Text = "<b>An error has occurred. Please try again later!</b></br>" + ex.Message;
lblMessage.CssClass = "text text-danger bold";
InfoPanel.CssClass = "panel panel-danger";
FormPanel.Visible = false;
FormPanel.Enabled = false;
}
}
protected void lbtPOFile2_Click(object sender, EventArgs e)
{
try
{
DownloadFile("poFileName2", "poFileContentType2", "poFileData2");
}
catch (Exception ex)
{
//Display message
InfoPanel.Visible = true;
lblMessage.Text = "<b>An error has occurred. Please try again later!</b></br>" + ex.Message;
lblMessage.CssClass = "text text-danger bold";
InfoPanel.CssClass = "panel panel-danger";
FormPanel.Visible = false;
FormPanel.Enabled = false;
}
}
protected void lbtPOFile3_Click(object sender, EventArgs e)
{
try
{
DownloadFile("poFileName3", "poFileContentType3", "poFileData3");
}
catch (Exception ex)
{
//Display message
InfoPanel.Visible = true;
lblMessage.Text = "<b>An error has occurred. Please try again later!</b></br>" + ex.Message;
lblMessage.CssClass = "text text-danger bold";
InfoPanel.CssClass = "panel panel-danger";
FormPanel.Visible = false;
FormPanel.Enabled = false;
}
}
一些相关的功能,以备不时之需:
// Validate link for employee (link format is View.aspx?guid=xxx&id=xxx)
public static bool ValidatePODetailLink(string guid, int poID)
{
using (SqlConnection con = new SqlConnection(CS))
{
string query = "SELECT COUNT(*) FROM PO WHERE poID = @poID AND poGUID = @guid";
SqlCommand cmd = new SqlCommand(query, con);
cmd.Parameters.AddWithValue("@guid", guid);
cmd.Parameters.AddWithValue("@poID", poID);
con.Open();
int i = Convert.ToInt32(cmd.ExecuteScalar());
if (i == 1) return true;
else return false;
}
}
//Get po request details for employee
public static DataTable GetPODetail(string guid, int poID)
{
using (SqlConnection con = new SqlConnection(CS))
{
string query = "SELECT * FROM PO WHERE poID = @poID AND poGUID = @guid";
SqlCommand cmd = new SqlCommand(query, con);
cmd.Parameters.AddWithValue("@guid", guid);
cmd.Parameters.AddWithValue("@poID", poID);
con.Open();
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
return dt;
}
}
发现问题:
我使用 UpdatePanel
并且只放置 <Triggers> <asp:PostBackTrigger ControlID="lbtPOFile" /> </Triggers>
因此它缺少 PostBackTrigger
for lbtPOFile2 和 lbtPOFile3。添加了这两行并且有效。
我建议采用以下方法。
将您的代码恢复到 "known good" 状态(它只能处理一个文件的下载,但这样做是正确的)
重构此代码,使其仍然支持单个文件下载。获取将文件内容流式传输到响应中的代码;将它移到一个单独的函数中(也许称之为
SendFile
);从您的点击处理程序调用该函数;重新编译并确认一切正常。现在修改
SendFile
以便它接受输入参数来确定它是否 return 文件 1、文件 2 或文件 3。修改点击处理程序以便它传了文件1的参数,重新编译测试,还是可以的现在为另外两个 link 按钮添加两个额外的点击处理程序。除了传递给
SendFile
的参数外,应该与您现有的点击处理程序相同。重新编译并测试所有三个文件。