我收到以下错误:服务器无法在发送HTTP标头后设置内容类型。我在网上看了一下,包括一些SO问题,但是没有一个问题解决了我的问题。这是我的特殊情况:
我有一个更新面板内的asp.net gridview(它也恰好位于modalpopupextender中)。 gridview有一个带有图像按钮的模板字段,单击该按钮可下载PDF。一切正常,直到我遇到试图下载的错误。我处理Gridview.RowCommand事件中的错误,并且页面不会像我想要的那样在客户端上更改。 然而,如果我再次单击下载,则文件不会下载,我在ScriptManager.AsyncPostBackError事件中捕获错误“服务器无法在发送HTTP标头后设置内容类型。”提前谢谢!
这是我的代码:
- Default.aspx的 -
<asp:HiddenField ID="hdnHiddenField" runat="server" />
<cc1:ModalPopupExtender ID="hdnHiddenField_mpeModalPopup" runat="server" Enabled="True" TargetControlID="hdnHiddenField"
CancelControlID="lnkClose" PopupControlID="pnlPanel" BackgroundCssClass="modalBackground"></cc1:ModalPopupExtender>
<asp:Panel ID="pnlPanel" runat="server" BorderStyle="Double" Width="50%" Height="75%" CssClass="modalPopup" style="overflow: auto; display: none">
<div class="modalHeaderClose">
<asp:LinkButton ID="lnkClose" runat="server" Text="Close [X]"></asp:LinkButton>
</div>
<cc1:Accordion ID="accdnPolicyInfo" runat="server" SelectedIndex="0" RequireOpenedPane="false">
<Panes>
<cc1:AccordionPane ID="accpnlDocuments" runat="server">
<Header>
<div class="accordionHeader">Documents</div>
</Header>
<Content>
<asp:UpdatePanel ID="upDocuments" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<div style="text-align: center; padding: 0 10px 10px 10px;">
<asp:GridView ID="gvGridView" runat="server" AutoGenerateColumns="False" Width="100%" ShowHeaderWhenEmpty="True">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:ImageButton ID="imgDownloadPDF" runat="server"
CommandArgument='<%# Bind("ImageKey") %>' CommandName="DownloadDocument"
ImageUrl="~/images/PDF-download.png" ToolTip="Download file to your computer" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
<EmptyDataRowStyle ForeColor="Red" HorizontalAlign="Center" />
</asp:GridView>
</div>
</ContentTemplate>
</asp:UpdatePanel>
</Content>
</cc1:AccordionPane>
</Panes>
</cc1:Accordion>
</asp:Panel>
- Default.aspx.vb -
Private Sub gvPolicyDocs_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles gvPolicyDocs.RowDataBound
Dim imgDownloadPDF As ImageButton = e.Row.FindControl("imgDownloadPDF")
If imgDownloadPDF IsNot Nothing Then
ScriptManager.GetCurrent(Page).RegisterPostBackControl(imgDownloadPDF)
'I just tried changing to RegisterAsyncPostBackControl method and found that I receive the same error even on the first attempt
End If
End Sub
Protected Sub gvPolicyDocs_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles gvPolicyDocs.RowCommand
Try
StreamPDF(e.CommandArgument, False)
Catch ex As Exception
ErrorHandler.HandleError(ex) 'sends out an email and returns back; ErrorHandler is an object I created
End Try
hdnHiddenField_mpeModalPopup.Show() 'otherwise modal popup disappears after return from postback
End Sub
Private Sub StreamPDF(ByVal strImageKey As String)
Dim dtImagePaths As DataTable
Dim oPDFManager As New PdfManager 'from ASPPDF library
Dim bytes() As Byte
Dim strImagePath As String = String.Empty
If String.IsNullOrEmpty(strImageKey) Then
Throw New Exception("Invalid Image Key")
End If
'Get image path from database
...
...
strImagePath = dtImagePaths.Rows(0).Item("ImagePath")
bytes = oPDFManager.OpenDocument(strImagePath).SaveToMemory()
'I checked that on the run after the error, bytes contains exactly what I want - so when I write it to a file locally, I can see the PDF
With Current
.Response.BufferOutput = False 'tried true and false
.Response.Clear()
.Response.ClearContent()
.Response.ClearHeaders()
.Response.ContentType = "application/pdf"
.Response.AddHeader("Content-Disposition", String.Format("{0}; filename={1}.pdf", IIf(bDownloadFile, "attachment", "inline"), strImageKey))
.Response.AddHeader("Content-Length", bytes.Length)
.Response.BinaryWrite(bytes)
.Response.Flush()
.Response.Close()
'Response.End() '--> See http://support.microsoft.com/kb/312629
.ApplicationInstance.CompleteRequest()
End With
End Sub
答案 0 :(得分:1)
答案 1 :(得分:0)
好吧,如果有其他人遇到这个问题,this article完全帮助了我。它基本上表明您无法在同一页面上下载和使用异步后备功能(通过UpdatePanel)。它演示了一种解决方法,其中所有下载代码都在完全独立的页面上完成,并且该页面在当前页面上的隐藏iframe中打开。另外,如果您也尝试在新窗口中打开pdf,则应用相同的解决方法,但不是向当前页面添加iframe,而是可以在JavaScript中调用window.open()。
答案 2 :(得分:0)
所以,我不确定如何在VB中解决这个问题,但我知道C#中这个问题的原因,因为我自己只需处理这个问题。
问题在于按钮本身。您需要使用ScriptManager注册该按钮。您无法在PageLoad()
事件中执行此操作,实际上您必须向该按钮添加OnInit
事件并在其中添加注册。
C#中的示例:
ASP页面代码:
<asp:ImageButton ID="imgDownloadPDF" runat="server" onInit="imgDownloadPDF_Init" ... />
代码背后:
protected void imgDownloadPDF_Init(object sender, EventArgs e)
{
ScriptManager.GetCurrent(this).RegisterPostBackControl(imgDownloadPDF);
}
我希望这会有所帮助。