从数据库检索 PDF 文件后,如何在新选项卡中打开 ASP.NET 中的 PDF 文件?

问题描述 投票:0回答:1

我正在开发 ASP.NET Webforms 应用程序,我需要检索一些在 SQL Server 数据库上存储为

Blob
的 PDF 文件。到目前为止,我可以从应用程序中看到表格上的文件,但我无法通过单击按钮打开它们。读取
byte[] array
的服务器端代码是这样的:

protected void btnOpenFile_Click(object sender, EventArgs e)
{
    List<BinaryServer> binaryFiles = bs.BinariesServer.GetBinariesServer(Token);

    Response.Clear();
    Response.AppendHeader("Content-Disposition", "filename=Test.pdf");
    Response.ContentType = "application/pdf";
    Response.BinaryWrite(binaryFiles[0].Blob);
    HttpContext.Current.Response.Flush();
    HttpContext.Current.Response.SuppressContent = true;
    HttpContext.Current.ApplicationInstance.CompleteRequest();
}

有趣的是,在调试上述代码时,它执行得很好,但是

Application_Error()
中的
Global.asax.cs
事件被引发,并且没有文件被打开。

我检查了以下解决方案,但没有一个有用。


事实上,我真正想做的是在

ListView
中列出文件(不仅是 PDF,还包括 Excel、txt 等),每个文件都有一个下载按钮,但对于 PDF 情况,我更愿意打开它在新选项卡中而不是直接下载。

c# asp.net webforms
1个回答
0
投票

好吧,假设我们有这个标记 - 网格视图:

    <asp:GridView ID="GridFiles" runat="server"
        AutoGenerateColumns="False" ShowHeaderWhenEmpty="true"
        CssClass="table table-hover" OnRowDataBound="GridFiles_RowDataBound"
        DataKeyNames="ID"
        >
        <Columns>
            <asp:BoundField DataField="FileName" HeaderText="FileName" />
            <asp:BoundField DataField="UpLoaded" HeaderText="UpLoaded" ItemStyle-Width="175" />
            <asp:TemplateField HeaderText="Preview" ItemStyle-HorizontalAlign="Center" >
                <ItemTemplate>
                    <asp:Image ID="imgPreview" runat="server" Height="80" />
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Download"  ItemStyle-HorizontalAlign="Center"  >
                <ItemTemplate>
                    <asp:LinkButton ID="cmdDownLoad"
                        runat="server" CssClass="btn myshadow"
                        OnClick="cmdDownLoad_Click" style="margin-top:20px" > 
                    <span aria-hidden="true" class="glyphicon glyphicon-cloud-download"></span>
                    </asp:LinkButton>
                </ItemTemplate>
            </asp:TemplateField>

            <asp:TemplateField HeaderText="Delete" ItemStyle-HorizontalAlign="Center">
                <ItemTemplate>
                    <asp:LinkButton ID="cmdDelete"
                        runat="server" CssClass="btn myshadow" style="margin-top:20px"
                        OnClick="cmdDelete_Click"> 
                    <span aria-hidden="true" class="glyphicon glyphicon-trash"></span>
                    </asp:LinkButton>
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>


    <script>

        function newtab() {
            var sURL = "ShowPdf.aspx"
            window.open(sURL, '_blank');
        }
    </script>

请注意按钮单击 - 我使用了 LinkButton,因为我想要一个“图标”,但简单的标准 asp.net 按钮也可以工作。

因此,如果文件不是 pdf,那么我们就下载,或者打开其他页面。

所以,按钮单击事件如下所示:

    protected void cmdDownLoad_Click(object sender, EventArgs e)
    {
        LinkButton myBut = (LinkButton)sender;
        GridViewRow gRow = (GridViewRow)myBut.NamingContainer; // get current grid row
        int PK = (int)GridFiles.DataKeys[gRow.RowIndex]["ID"];

        SqlCommand cmdSQL = new SqlCommand("SELECT * FROM tblFiles WHERE ID = @ID");
        cmdSQL.Parameters.Add("@ID", SqlDbType.Int).Value = PK;

        DataTable dt = General.MyRstP(cmdSQL);
        string strFile = dt.Rows[0]["FileName"].ToString();

        if (Path.GetExtension(strFile).ToUpper() == ".PDF")
        {
            // This is a pdf, so setup pk for display page
            Session["PK"] = PK;
            string sJava = "newtab();";

            ScriptManager.RegisterStartupScript(this.Page, Page.GetType(), "myjump", sJava, true);
        }
        else
        {
            string sMineType = MimeMapping.GetMimeMapping(strFile);
            byte[] FileData = (byte[])dt.Rows[0]["FileB"];

            Response.ContentType = sMineType;
            Response.AppendHeader("Content-Disposition", "attachment; filename=" + strFile);
            Response.BinaryWrite(FileData);
            Response.End();    
        }
    }

所以,如果是pdf,那么我们设置PK值,并调用JavaScript例程在新选项卡上跳转到新页面。

新页面有以下代码:

    protected void Page_Load(object sender, EventArgs e)
    {
        int PK = (int)Session["PK"];
        SqlCommand cmdSQL = new SqlCommand("SELECT * FROM tblFiles WHERE ID = @ID");
        cmdSQL.Parameters.Add("@ID", SqlDbType.Int).Value = PK;

        DataTable dt = General.MyRstP(cmdSQL);
        string strFile = dt.Rows[0]["FileName"].ToString();
        string sMineType = MimeMapping.GetMimeMapping(strFile);

        byte[] FileData = (byte[])dt.Rows[0]["FileB"];

        Response.ContentType = sMineType;
        Response.AddHeader("Content-Disposition", $"inline; filename={strFile}");
        Response.BinaryWrite(FileData);
        Response.End();

    }

结果是这样的:

所以,并不是拉取二进制文件然后尝试在新页面上显示。

检查文件类型,如果是 PDF,则将数据库 PK 值保存到会话中,然后运行一些 JavaScript 在新选项卡中打开新页面,然后该页面将按照以下方式加载/显示 pdf上面。

© www.soinside.com 2019 - 2024. All rights reserved.