使用ASPX页面上的响应下载PDF,仅在Page_Load

时间:2017-02-28 14:33:35

标签: asp.net vb.net http pdf download

我已经看到了几个与使用Response从Web浏览器下载PDF相关的问题,但似乎没有一个问题符合我所遇到的神秘问题。

我正在开发一个项目,要求用户能够单击按钮(btnPDF),立即将具有特定“ID”字符串的Telerik报告的PDF下载到Downloads文件夹。此过程最初位于IIS上的ASPX页面,与按钮所在的位置不同。单击btnPDF时,我使用Response.Redirect通过该页面下载PDF。下载PDF的代码如下所示:

Response.Clear()
Response.ContentType = result.MimeType 'this is always "application/pdf"
Response.Cache.SetCacheability(HttpCacheability.Private)
Response.Expires = -1
Response.Buffer = True
Response.AddHeader("Content-Disposition", String.Format("{0};FileName={1}", "attachment", fileName))
Response.BinaryWrite(result.DocumentBytes)
Response.End()

请注意,result.DocumentBytes是一个包含PDF正确字节的字节数组。

此代码工作正常。现在,我需要将流程合并到btnPDF所在的同一页面上,而不是将流程放在单独的项目中,这样当您单击时btnPDF,调用一个执行相同任务的子程序。我认为这很容易,几乎是复制和粘贴。使用在新子例程中添加的相同代码,这就是我的单击事件处理程序“ButtonPDF_Click”现在的样子:

Protected Sub ButtonPDF_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnPDF.Click

    DownloadReportPDF(Me.RadGrid1.SelectedValue.ToString())

    Dim strMessage As String = "alert('Printed PDF Sheet.');"
    ScriptManager.RegisterStartupScript(Me, Me.GetType, "MyScript", strMessage, True)

End Sub

Protected Sub DownloadReportPDF(ByVal releaseMasterId As String)
    'Service call to generate report source
    Dim service As New TelerikReportLibrary.ReportServices.PPSReportService
    Dim source As Telerik.Reporting.TypeReportSource = service.GetReportSource(releaseMasterId)

    'Render PDF and download
    Dim reportProcessor As New ReportProcessor()
    Dim result As RenderingResult = reportProcessor.RenderReport("PDF", source, Nothing)

    Dim fileName As String = result.DocumentName + "_" + releaseMasterId + "." + result.Extension

    Response.Clear()
    Response.ContentType = result.MimeType 'this is always "application/pdf"
    Response.Cache.SetCacheability(HttpCacheability.Private)
    Response.Expires = -1
    Response.Buffer = True
    Response.AddHeader("Content-Disposition", String.Format("{0};FileName={1}", "attachment", fileName))
    Response.BinaryWrite(result.DocumentBytes)
    Response.End()

End Sub

但PDF不再下载。仍会创建准确的字节数组,但响应部分不会导致从浏览器下载PDF。我发现在同一页面的Page_Load处理程序中调用DownloadReportPDF可以像以前一样成功生成和下载PDF。

我看不出为什么这不起作用的原因,但我是ASP新手,我在VB中并不出色。我已经尝试过使用Response.OutputStream,Response.WriteFile,并使用MemoryStream,以及其他一些我已经忘记的事情。我希望有一些简单的东西,也许是某些属性的页面或btnPDF我可能会丢失。这是btnPDF的标记,以防万一:

    <asp:linkButton ID="btnPDF" CssClass="btn btn-default" runat="server" Width="115px">
        <i class="fa fa-file-text" title="Edit"></i> PDF
    </asp:linkButton>

可能导致这样的问题?我应该在哪里看这一点?

如果需要更多信息,请与我们联系。

谢谢, 沙恩

编辑:

我尝试在btnPDF_Click上设置会话变量,并在回发时处理PDF下载。同样,生成了一个有效的字节数组,但是HttpResponse没有导致PDF从浏览器下载。

编辑:

在最后一次编辑的基础上,这告诉我从Page_Load调用DownloadReportPDF仅在IsPostBack为false时才有效。我刚刚测试了这个想法,这是正确的。在上面的代码中,如果我在尝试下载PDF时检查IsPostBack,那是真的。进一步调查。

1 个答案:

答案 0 :(得分:0)

好吧,我终于找到了一个我满意的解决方案(尽管我仍然不明白为什么我可以使用Response下载PDF而IsPostBack是真的)。

this thread的启发,我将之前发布的代码放在名为PDFDownloadHandler的HttpHandler中,然后在btnPDF_Click事件处理程序中使用Response.Redirect来使用PDFDownloadHandler。 This article在这个过程中给了我很多帮助,因为这是我以前没有做过的事情。

如果有其他人遇到此问题,这里是新的PDFDownloadHandler:

Imports Microsoft.VisualBasic
Imports System.Web
Imports Telerik.Reporting
Imports Telerik.Reporting.Processing

Public Class PDFDownloadHandler
    Implements IHttpHandler

    Public Sub ProcessRequest(ByVal context As  _
            System.Web.HttpContext) Implements _
            System.Web.IHttpHandler.ProcessRequest
        Dim request As HttpRequest = context.Request
        Dim response As HttpResponse = context.Response

        Dim path As String = request.Path
        If path.Contains("pps.pdfdownload") Then
            Dim releaseMasterId As String = request.QueryString("ID")
            If releaseMasterId IsNot Nothing Then
                'Service call to generate report source
                Dim service As New TelerikReportLibrary.ReportServices.PPSReportService
                Dim source As Telerik.Reporting.TypeReportSource = service.GetReportSource(releaseMasterId)

                'Render PDF and save
                Dim reportProcessor As New ReportProcessor()
                Dim result As RenderingResult = reportProcessor.RenderReport("PDF", source, Nothing)

                Dim fileName As String = result.DocumentName + "_" + releaseMasterId + "." + result.Extension

                response.Clear()
                response.ContentType = result.MimeType
                response.Cache.SetCacheability(HttpCacheability.Private)
                response.Expires = -1
                response.Buffer = True
                response.AddHeader("Content-Disposition", String.Format("{0};FileName={1}", "attachment", fileName))
                response.BinaryWrite(result.DocumentBytes)
            End If
        End If

        response.End()
    End Sub

    Public ReadOnly Property IsReusable() As Boolean _
            Implements System.Web.IHttpHandler.IsReusable
        Get
            Return False
        End Get
    End Property
End Class

非常感谢任何有关原始技术不起作用的进一步见解。