如何从更新面板中的面板下载pdf

时间:2022-06-18 09:48:22

I have a site that uses master pages.

我有一个使用母版页的网站。

One of my content pages is basically a large UpdatePanel. Inside that UpdatePanel is a regular Panel. Inside the regular Panel is a Gridview. Inside the Gridview is a Linkbutton that points to a pdf stored in my database.

我的一个内容页面基本上是一个大型的UpdatePanel。 UpdatePanel内部是一个常规Panel。常规Panel内部是Gridview。 Gridview内部是一个Linkbutton,指向存储在我的数据库中的pdf。

When I click the Linkbutton to retrieve the pdf, nothing happens.

当我单击Linkbutton来检索pdf时,没有任何反应。

I have this working on another page that has no UpdatePanel.

我在另一个没有UpdatePanel的页面上工作。

I have already tried firing an 'external' button from the Linkbutton and registering this button as a PostBack event. The page posts back when I click the Linkbutton but the pdf is not being sent to the user.

我已经尝试从Linkbutton触发“外部”按钮并将此按钮注册为PostBack事件。单击“链接”按钮时页面会回发,但不会将pdf发送给用户。

Here is some sample code:

以下是一些示例代码:

<asp:UpdatePanel ID="UpdatePanelClaims" runat="server">
<ContentTemplate>

<asp:Panel ID="upClaimAttachment" runat="server" Visible="false" >

        <table id="gridClaimAttachmentTable" runat="server" class="table" >
            <tr>
                <td >
                    <asp:GridView ID="grdClaimAttachment" runat="server" AllowPaging="True" AllowSorting="True" 
                        AutoGenerateColumns="False" CssClass="table table-striped table-bordered table-condensed table-hover" EmptyDataText="No Attachments for this Claim."
                        EnableTheming="False" onpageindexchanging="grdClaimAttachment_PageIndexChanging"   PageSize="15" OnRowCommand="grdClaimAttachment_RowCommand"
                        OnRowDataBound="grdClaimAttachment_RowDataBound" >
                        <PagerStyle CssClass="bs-pagination" />
                        <AlternatingRowStyle CssClass="alternateColor" />
                        <RowStyle CssClass="rowsStyle" />
                        <Columns>
                            <asp:BoundField DataField="ID" HeaderText="ID" ItemStyle-CssClass="hideColumn" HeaderStyle-CssClass="hideColumn" >
                                <HeaderStyle HorizontalAlign="Left" />
                                <ItemStyle HorizontalAlign="Right" />
                            </asp:BoundField>
                            <asp:TemplateField HeaderText="File Name">
                                <ItemTemplate>
                                    <asp:LinkButton ID="btnViewAttachment" Text='<%#Eval("FileName") %>' CommandName="ViewAttachment"
                                        CommandArgument="<%# Container.DataItemIndex %>" runat="server"></asp:LinkButton></ItemTemplate>
                            </asp:TemplateField>

                            <asp:ButtonField ButtonType="Button" CommandName="btnDelete" Text="Delete">
                                <ControlStyle CssClass="btn btn-info btn-xs " />
                            </asp:ButtonField>
                        </Columns>
                        <SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
                        <SortedAscendingCellStyle BackColor="#E9E7E2" />
                        <SortedAscendingHeaderStyle BackColor="#506C8C" />
                        <SortedDescendingCellStyle BackColor="#FFFDF8" />
                        <SortedDescendingHeaderStyle BackColor="#6F8DAE" />
                    </asp:GridView>
                </td>
            </tr>
            <tr >
                <td>
                    <div class="container">
                        <div class="form-group form-group-sm form-groupNoSpace">
                            <div class="row">
                                <div class=" col-xs-4 col-xs-offset-4 text-right">
                                    <asp:Button ID="btnClaimAttachmentAdd" runat="server" CssClass="btn btn-primary btn-sm btn-block" Text="Add Attachment" OnClick="btnClaimAttachmentAdd_Click"/>
                                </div>
                            </div>
                        </div>
                        </div>

                </td>
            </tr>
        </table>

</asp:Panel> <%-- Attachment Update Panel --%>

<asp:Button ID="btnClickMe" runat="server" OnClick="btnClickMe_Click" Visible="false" />

</ContentTemplate>
  <Triggers>
      <asp:PostBackTrigger ControlID="btnClickMe" />
  </Triggers>
</asp:UpdatePanel> <%-- UpdatePanelClaims --%>

In the code behind I have this:

在后面的代码我有这个:

    protected void btnClickMe_Click(object sender, EventArgs e, ClaimAttachment objAttachment)
    {
        ViewAttachment(objAttachment);
    }

    private void ViewAttachment(ClaimAttachment objAttachment)
    {
        Response.Clear();
        Response.Buffer = true;
        Response.ContentType = "application/pdf";
        Response.AppendHeader("content-disposition", "attachment;filename=" + objAttachment.FileName);
        Response.Charset = "";
        Response.Cache.SetCacheability(HttpCacheability.NoCache);
        Response.BinaryWrite(objAttachment.Attachment);
        Response.Flush();
        Response.End();
    }

UPDATE: Forgot some critical code!

更新:忘了一些关键代码!

    protected void grdClaimAttachment_RowCommand(object sender, GridViewCommandEventArgs e)
    {
        try
        {
            int index = Convert.ToInt32(e.CommandArgument);

            if (index >= grdClaimAttachment.Rows.Count)
                return;

            int IDkey = Convert.ToInt32(grdClaimAttachment.Rows[index].Cells[0].Text);
            ClaimAttachment objClaimAttachment = ClaimAttachment.RetrieveById((string)Session["Username"], IDkey);

            if (e.CommandName == "btnDelete")
            {
                ltlDeleteID.Text = IDkey.ToString();
                ltlRecordType.Text = "attachment";
                confirmDialog(string.Format("DELETE Attachment: {0} ?", objClaimAttachment.FileName));
            }
            else if (e.CommandName == "ViewAttachment")
            {
                //btnClickMe.CommandArgument = IDkey.ToString();
                //btnClickMe_Click(sender, e);
                btnClickMe.Click += new EventHandler((s1, e1) => btnClickMe_Click(s1, e1, objClaimAttachment));
                btnClickMe_Click(sender, e, objClaimAttachment);
            }
        }
        catch (BLException be)
        {
            errDialog(be.Message);
        }
    }

The Linkbutton in the grid is actually calling the Click event of an external button to perform the pdf download...

网格中的Linkbutton实际上是调用外部按钮的Click事件来执行pdf下载...

What am I missing?? Like I said, this works if I remove all UpdatePanels but I need them for other things...

我错过了什么?就像我说的,如果我删除所有UpdatePanel但我需要它们用于其他事情,这是有效的...

thx!

1 个解决方案

#1


The PostBackTrigger class is key to your solution, as it can be used to trigger the full page reload required for the download reponse to work. Downloads simply will not work from a partial postback.

PostBackTrigger类是解决方案的关键,因为它可用于触发下载响应所需的完整页面重新加载。下载根本不适用于部分回发。

However, as the buttons that should trigger the postback are inside your grid, using a single PostBackTrigger in the page markup is not enough, you need a specific trigger for each button / row.

但是,由于应该触发回发的按钮位于网格中,因此在页面标记中使用单个PostBackTrigger是不够的,您需要为每个按钮/行指定一个特定的触发器。

Use something like this (call it from your Page_Load)

使用这样的东西(从你的Page_Load调用它)

private void RegisterPostBackControls()
{
    foreach (GridViewRow row in grdClaimAttachment.Rows)
    {
        LinkButton button = row.FindControl("btnViewAttachment") as LinkButton;
        ScriptManager.GetCurrent(this).RegisterPostBackControl(button);
    } 
}

#1


The PostBackTrigger class is key to your solution, as it can be used to trigger the full page reload required for the download reponse to work. Downloads simply will not work from a partial postback.

PostBackTrigger类是解决方案的关键,因为它可用于触发下载响应所需的完整页面重新加载。下载根本不适用于部分回发。

However, as the buttons that should trigger the postback are inside your grid, using a single PostBackTrigger in the page markup is not enough, you need a specific trigger for each button / row.

但是,由于应该触发回发的按钮位于网格中,因此在页面标记中使用单个PostBackTrigger是不够的,您需要为每个按钮/行指定一个特定的触发器。

Use something like this (call it from your Page_Load)

使用这样的东西(从你的Page_Load调用它)

private void RegisterPostBackControls()
{
    foreach (GridViewRow row in grdClaimAttachment.Rows)
    {
        LinkButton button = row.FindControl("btnViewAttachment") as LinkButton;
        ScriptManager.GetCurrent(this).RegisterPostBackControl(button);
    } 
}