从数据库下载同一记录中的多个文件 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 lbtPOFile2lbtPOFile3。添加了这两行并且有效。

我建议采用以下方法。

  1. 将您的代码恢复到 "known good" 状态(它只能处理一个文件的下载,但这样做是正确的)

  2. 重构此代码,使其仍然支持单个文件下载。获取将文件内容流式传输到响应中的代码;将它移到一个单独的函数中(也许称之为 SendFile);从您的点击处理程序调用该函数;重新编译并确认一切正常。

  3. 现在修改 SendFile 以便它接受输入参数来确定它是否 return 文件 1、文件 2 或文件 3。修改点击处理程序以便它传了文件1的参数,重新编译测试,还是可以的

  4. 现在为另外两个 link 按钮添加两个额外的点击处理程序。除了传递给 SendFile 的参数外,应该与您现有的点击处理程序相同。重新编译并测试所有三个文件。