2012-02-07 46 views
0

我正在使用DataGridView來顯示語句列表。其中一列是LinkBut​​ton,它允許您下載PDF格式的特定語句。我的代碼完全適用於所有瀏覽器,IE7 & IE8除外。我不知道這是爲什麼。IE7/8:PDF文件不會用HTTP GET下載

 <asp:GridView ID="dgvEStatements" runat="server" EnableSortingAndPagingCallbacks="False" 
      EnableViewState="true" GridLines="Vertical" Width="100%" AutoGenerateColumns="False" 
      CssClass="gridheader" EmptyDataText="<%$ Resources:IBEStatements, dgvEStatements_NoRows %>" 
      OnPageIndexChanging="dgvEStatements_PageIndexChanging" OnRowCommand="dgvEStatements_RowCommand" 
      OnRowDataBound="dgvEStatements_RowDataBound"> 
      <Columns> 
       <asp:BoundField DataField="Date" HeaderText="<%$ Resources:IBEStatements, dgvEStatements_DateHeader %>" 
        HeaderStyle-CssClass="lhs"> 
        <ItemStyle CssClass="lhs" /> 
       </asp:BoundField> 
       <asp:BoundField DataField="Description" HeaderText="<%$ Resources:IBEStatements, dgvEStatements_DescriptionHeader %>" 
        HeaderStyle-CssClass="lhs" /> 
       <asp:BoundField DataField="DocumentType" Visible="false" HeaderText="<%$ Resources:IBEStatements, dgvEStatements_DocumentTypeHeader %>" 
        HeaderStyle-CssClass="lhs"> 
        <ItemStyle CssClass="lhs" /> 
       </asp:BoundField> 
       <asp:TemplateField> 
        <ItemTemplate> 
         <asp:LinkButton ID="lnkDownloadEStatement" runat="server" Text="<%$ Resources:IBEStatements, lnkDownloadEStatement %>" /> 
        </ItemTemplate> 
        <ItemStyle CssClass="rhs" /> 
       </asp:TemplateField> 
      </Columns> 

     </asp:GridView> 

的RowDataBound事件對電網進行以下操作:

protected void dgvEStatements_RowDataBound(object sender, GridViewRowEventArgs e) 
{ 

    if (e.Row.RowType == DataControlRowType.DataRow) 
    { 
     LinkButton lnkEStatement = (LinkButton)e.Row.FindControl("lnkDownloadEStatement"); 

     string fileId = DataBinder.Eval(e.Row.DataItem, "StatementID").ToString(); 
     lnkEStatement.Attributes.Add("onclick", "javascript:EStatementDownload('" + fileId + "'); return false;"); 
    }   
} 

JavaScript函數來調用創建的PDF頁面:背後

function EStatementDownload(fileid) { 
    var iframe = document.createElement("iframe"); 
    iframe.src = "EStatementFile.ashx?fileid=" + fileid; 
    iframe.style.display = "none"; 
    document.body.appendChild(iframe); 
} 

最後,代碼爲EStatementFile。 ashx看起來像這樣:

public void ProcessRequest(HttpContext context) 
    { 
     try 
     { 
      string args = context.Request.QueryString["fileid"].ToString(); 

      int statementID = 0; 
      int.TryParse(args, out statementID); 

      string documentID = String.Empty; 
      string accountnumber = String.Empty; 
      DateTime fileDate = DateTime.MinValue; 

      foreach (EStatement item in EStatementListing.EStatements) 
      { 
       if (statementID == item.StatementID) 
       { 
        documentID = item.DocumentID; 
        accountnumber = item.AccountNumber; 
        fileDate = item.DocumentDate; 
        break; 
       } 
      } 

      EStatementFacade estatementFacade = new EStatementFacade(); 
      EStatement estatement = estatementFacade.GetEStatement(documentID, accountnumber, fileDate); 
      if (estatement.Document != null) 
      { 
       context.Response.Clear(); 
       context.Response.ContentType = "Application/pdf"; 
       context.Response.Cache.SetCacheability(HttpCacheability.Private); 
       context.Response.AppendHeader("Cache-Control", "private; must-revalidate"); 
       context.Response.AppendHeader("Pragma", "private"); 
       context.Response.AddHeader("content-disposition", "attachment; filename=" + fileDate.ToString("ddMMyyyy") + ".pdf"); 
       context.Response.BinaryWrite(estatement.Document); 
       context.Response.Flush();          
      } 
     } 
     catch (Exception ex) 
     { 
     } 
     finally 
     { 
      context.ApplicationInstance.CompleteRequest(); 
     } 
    } 

當點擊電網LinkBut​​ton的,下面的JavaScript信息顯示在Firebug的,這可能是在尋找問題的有用: Firebug Output

一些有趣的注意,如果我叫context.Response.End()直接在context.Response.Flush()之後,我得到以下異常。現在文件下載對話框仍然在所有的瀏覽器中顯示,不管有沒有例外,但在IE7 & IE8中,仍然沒有下載對話框。

context.Response.End(); 'context.Response.End()'拋出了類型'System.Threading.ThreadAbortException'的異常 base {System.SystemException}:{無法評估表達式,因爲代碼已經過優化或本機框架處於調用之上} ExceptionState:無法評估表達式,因爲代碼已經過優化或本機框架位於調用堆棧之上。

它可能與iFrame有關?

enter image description here

PS:保存的最後一個圖像圖看大圖

+0

什麼行爲,你在看IE7/8? – RoccoC5 2012-02-07 23:32:55

+0

當我點擊LinkBut​​ton時,沒有任何反應......沒有下載文件對話框。 – FaNIX 2012-02-07 23:49:07

+0

要到Response.End調用(當忽略ThreadAbortException),你將需要添加一個嘗試捕捉和忽略例外。 嘗試 { 到Response.End(); } 趕上(例外前){ 如果 (當然是ThreadAbortException) {// 無能爲力 } 其他 { 扔; }} 我 – 2012-02-08 00:09:29

回答

1

這裏是計算器,我有這聽起來像同樣的問題後。

IE8和更低版本無法處理Cache-control標題並導致靜態內容(如PDF)無法下載。

Link

+1

試圖消除Cache-Control頭,並同樣的事情發生......這是什麼。 – FaNIX 2012-02-07 23:40:26

1

兩件事情:

1)清除之前建立在你的處理器的響應你的頭的所有。這解決了我的Microsoft安全公告MS11-100導致在Cache-Control頭是越來越設置爲no-cache="Set-Cookie"的問題(見this blog post更多信息):

// snip... 

if (estatement.Document != null) 
{ 
    context.Response.ClearHeaders(); 
    context.Response.Clear(); 
    context.Response.ContentType = "Application/pdf"; 
    // snip... 

2)我不知道這是否是實際上導致了任何問題,但是每次用戶下載PDF時不是創建一個iframe,爲什麼不設置window.location屬性呢?這樣,你不加入「用完即棄」的iframe的文檔,行爲仍然應該是相同的:

function EStatementDownload(fileid) { 
    window.location = "EStatementFile.ashx?fileid=" + fileid; 
} 
+0

感謝,對window.location的是做比使用一個iFrame的方式更好的辦法。它仍然不能解決問題,但我認爲這是一個增強。感謝您的 – FaNIX 2012-02-08 01:29:03

2

你可以嘗試這個 -

Response.Buffer = true; 
      Response.Clear(); 
      Response.ClearContent(); 
      Response.ClearHeaders(); 
      Response.ContentType = "application/pdf"; 
      Response.AddHeader(
       "Content-Disposition", 
       string.Format("attachment; filename={0}",filename) 
      ); 
      // stream pdf bytes to the browser 
      Response.OutputStream.Write(estatement.Document, 0, estatement.Document.Length); 
      Response.End(); 
+0

代碼完全在所有瀏覽器,但仍然無法在IE7或IE8工作。仍然沒有顯示文件下載對話框:( – FaNIX 2012-02-08 01:39:51

+0

你可以嘗試使用window.open ScriptManager.RegisterStartupScript(這一點,this.GetType(), 「redirectScript」 的String.Format(「window.open( '{0}','_空白');「,handlerUrl),true); inplace of window.location其中handlerUrl是你的ashx url – DotNetUser 2012-02-08 02:10:21