我有这个表存储采购订单数据,它最多可以容纳3个文件(第一个文件是必需的,第二个和第三个是可选的),它们的列名在图片中突出显示。
我已经完成了上传页面,它保存了用户输入和上传到数据库的所有数据,工作正常,我可以在表格中看到所有已保存的文件名和字节。
我正在使用“查看”页面,该页面从数据库中检索数据并将其显示在网页上,检索文件存在问题。
这个想法是向页面显示文件名(工作正常),当用户点击文件名时,他们可以将其保存到计算机(或打开/运行等依赖于Web浏览器提示窗口), 问题:我只能保存第一个文件,当点击第二个和第三个文件名时,没有任何事情发生,尽管在调试模式下它们(名称,类型和file2和file3的数据确实存在但是没有出现保存文件的提示窗口
任何想法如何解决这个问题,或者如果有人有更好的方法来下载这些文件,请帮忙。
这是我的代码(请忽略不相关的代码或如果您想知道他们做了什么,请告诉我们):
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个参数,它们只是数据库表中的列名,对应于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>
因此 lbtPOFile2 和 lbtPOFile3 缺少PostBackTrigger
。添加了这两行,它确实有效。
答案 0 :(得分:2)
我建议采用以下方法。
将您的代码还原为&#34;已知商品&#34; state(它只能处理一个文件的下载,但是正确地处理)
重构此代码,使其仍支持单个文件下载。获取将文件内容流式传输到响应中的代码;将它移动到一个单独的函数中(也许称之为SendFile
);从你的点击处理程序调用该函数;重新编译并确认一切仍然有效。
现在修改SendFile
,使其接受输入参数,确定是否返回文件1,文件2或文件3.修改单击处理程序,使其传递指示文件1的参数。重新编译并重新测试,确保它仍然有效。
现在为其他两个链接按钮添加两个额外的点击处理程序。应该与现有的单击处理程序相同,但传递给SendFile
的参数除外。用所有三个文件重新编译和测试。