2017-02-28 65 views
2

我已經看到了幾個有關使用Response從Web瀏覽器下載PDF的問題,但似乎沒有一個適合我遇到的神祕問題。在ASPX頁面下載PDF只在Page_Load中工作

我正在開發一個項目,該項目要求用戶能夠單擊按鈕(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,以及其他一些我已經失去蹤跡的東西。我希望有一些簡單的東西,也許我可能會遺失Page或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是假的。我只是測試了這個想法,它是真實的。在上面的代碼中,如果我在檢查IsPostBack的時候嘗試下載PDF文件,這是真的。進一步調查。

+0

我認爲這個問題肯定與按鈕點擊啓動回發有關。你可能需要玩'IsPostBack' ... – Pikoh

+0

你在更新面板裏做異步嗎? –

+0

@Pikoh:我重新配置了使用IsPostBack和會話變量的過程,但問題依然存在。請參閱編輯後。謝謝! (另外,就我所知,我沒有做異步帖子) –

回答

0

好吧,我終於找到了我滿意的解決方案(儘管我仍然不明白爲什麼我無法使用Response而IsPostBack爲true來下載PDF)。

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 

爲什麼原來的技術沒有工作的任何進一步的深入瞭解是極大的讚賞。