从数据库表中下载同一记录中的多个文件

时间:2015-07-24 17:24:03

标签: c# asp.net sql-server file-upload webforms

我有这个表存储采购订单数据,它最多可以容纳3个文件(第一个文件是必需的,第二个和第三个是可选的),它们的列名在图片中突出显示。

enter image description here

我已经完成了上传页面,它保存了用户输入和上传到数据库的所有数据,工作正常,我可以在表格中看到所有已保存的文件名和字节。

我正在使用“查看”页面,该页面从数据库中检索数据并将其显示在网页上,检索文件存在问题

这个想法是向页面显示文件名(工作正常),当用户点击文件名时,他们可以将其保存到计算机(或打开/运行等依赖于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。添加了这两行,它确实有效。

1 个答案:

答案 0 :(得分:2)

我建议采用以下方法。

  1. 将您的代码还原为&#34;已知商品&#34; state(它只能处理一个文件的下载,但是正确地处理)

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

  3. 现在修改SendFile,使其接受输入参数,确定是否返回文件1,文件2或文件3.修改单击处理程序,使其传递指示文件1的参数。重新编译并重新测试,确保它仍然有效。

  4. 现在为其他两个链接按钮添加两个额外的点击处理程序。应该与现有的单击处理程序相同,但传递给SendFile的参数除外。用所有三个文件重新编译和测试。