我已经看到了几个与使用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,那是真的。进一步调查。
答案 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
非常感谢任何有关原始技术不起作用的进一步见解。