Asp.net 使用ASPX页面上的响应下载PDF,仅在页面加载中工作
我见过几个关于使用Response从Web浏览器下载PDF的问题,但似乎没有一个与我遇到的神秘问题相符 我正在从事一个项目,该项目要求用户能够单击按钮(btnPDF),立即将带有特定“ID”字符串的Telerik报告的PDF下载到下载文件夹。此进程最初位于与按钮所在位置不同的IIS上的ASPX页面中。单击btnPDF时,我使用Response.Redirect通过该页面下载PDF。下载PDF的代码如下所示:Asp.net 使用ASPX页面上的响应下载PDF,仅在页面加载中工作,asp.net,vb.net,http,pdf,download,Asp.net,Vb.net,Http,Pdf,Download,我见过几个关于使用Response从Web浏览器下载PDF的问题,但似乎没有一个与我遇到的神秘问题相符 我正在从事一个项目,该项目要求用户能够单击按钮(btnPDF),立即将带有特定“ID”字符串的Telerik报告的PDF下载到下载文件夹。此进程最初位于与按钮所在位置不同的IIS上的ASPX页面中。单击btnPDF时,我使用Response.Redirect通过该页面下载PDF。下载PDF的代码如下所示: Response.Clear() Response.ContentType = resu
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的正确字节
这段代码运行得很好。现在,我需要将流程合并到btnPDFis所在的同一页面上,而不是在单独的项目中的单独页面上,这样当您单击btnPDF时,将调用执行相同任务的子例程。我认为这将是非常容易的,几乎是一个复制和粘贴。在新的子例程中添加了相同的代码后,我的click事件处理程序“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。我发现在同一页面上的页面加载处理程序中调用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>
PDF
是什么导致了这样的问题?我应该从哪里看这一点
如果需要更多信息,请告诉我
谢谢,
谢恩
编辑:
我尝试在btnPDF_Click上设置会话变量,并在回发时处理PDF下载。同样,生成了一个有效的字节数组,但是HttpResponse没有导致从浏览器下载PDF
编辑:
在上一次编辑的基础上,这告诉我,仅当IsPostBack为false时,从Page_Load调用DownloadReportPDF才有效。我刚刚测试了这个想法,它是正确的。在上面的代码中,如果我在尝试下载PDF时检查IsPostBack,这是真的。进一步调查。好吧,我终于找到了一个我满意的解决方案(尽管我仍然不明白为什么我不能使用Response下载PDF,而IsPostBack是真的) 受此启发,我将先前发布的代码放入名为PDFDownloadHandler的HttpHandler中,然后在btnPDF_Click事件处理程序中使用Response.Redirect来利用PDFDownloadHandler。在这个过程中帮助了我很多,因为这是我以前没有做过的事情 如果其他任何人遇到此问题,以下是新的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
对于最初的技术为什么不起作用的任何进一步见解,我们都非常感谢。我认为问题一定与按钮单击启动回发有关。您可能需要使用
IsPostBack
…是否在更新面板中执行异步post?@Pikoh:我使用IsPostBack和会话变量重新配置了流程,但问题仍然存在。请参阅编辑后的文章。谢谢(另外,据我所知,我没有做异步post)