2012-07-10 77 views
3

我花了最近幾天試圖解決這個問題。我已經進行了詳盡的谷歌搜索,嘗試了很多解決方案,沒有運氣。CSV導出Response.End異常拋出

實質上,我試圖將數據導出到CSV並下載它。該代碼有效,但會引發異常。我的特殊用法需要多次下載(如下面的例子)緊接着發生,但異常可以防止發生這種情況。

string attachment = string.Format("attachment; filename={0}_OutPut.csv", companyName); 

HttpContext.Current.Response.Clear(); 
HttpContext.Current.Response.ClearHeaders(); 
HttpContext.Current.Response.ClearContent(); 
HttpContext.Current.Response.AddHeader("content-disposition", attachment); 
HttpContext.Current.Response.ContentType = "text/csv"; 
HttpContext.Current.Response.AddHeader("Pragma", "public"); 
WriteColumnName("Column1,Column2,Column3"); 

StringBuilder stringBuilder = new StringBuilder(); 

foreach (Item i in list.Items) 
{ 
    AddData(i.TaxCodeValue.ToString(), stringBuilder); 
    AddData(i.Description.ToString(), stringBuilder); 
    AddData(i.Description.ToString(), stringBuilder); 

    stringBuilder.Length = 0; //Reset Stringbuilder value 
    HttpContext.Current.Response.Write(stringBuilder.ToString()); 
    HttpContext.Current.Response.Write(Environment.NewLine); 
} 

HttpContext.Current.Response.End(); <---This is the problem 

我讀過:

http://support.microsoft.com/kb/312629

Alternative to Response.End()?

Thread was being aborted when exporting to excel?

我明白到Response.End()拋出一個異常,因爲它正在中止線程(一般不建議)。但是,對於我的情況,我沒有看到任何替代方案。

幾個我試過的東西:

  1. HttpContext.Current.ApplicationInstance.CompleteRequest();作爲替代到Response.End()。它導致我的CSV被填充垃圾,而不是我正在寫的實際數據。
  2. HttpContext.Current.Response.Redirect("Page.aspx", false);只是刷新頁面,並且不下載寫入的數據。
  3. 捕獲catch塊中的異常。它總是設法逃脫並漣漪。

任何想法?

預先感謝您。

+0

你是什麼意思多次下載?一個文件有很多記錄,或者你的意思是一個文件在另一個之後? – Oded 2012-07-10 21:06:20

+0

下載一個文件後(換句話說,上面的代碼在我的實際實現中爲不同的文件重複了幾次)。 – Sc0rpio 2012-07-10 21:13:43

+0

您是否在Response.End()之前嘗試了'Response.Flush()'?順便說一下,我不確定您可以在單個回覆中發送多個文件。 – Oded 2012-07-10 21:14:55

回答

0

當您在此處輸出文件到流時,基本上必須「劫持」Page的正常流。您應該改爲使用通用處理程序(實現IHttpHandler的.ashx文件)。

實施通用處理程序時,您不必擔心呼叫Response.ClearResponse.End,因爲您將自行提供完整響應。然後,您的頁面將鏈接到ashx處理程序,傳遞必要的查詢字符串參數以加載您的數據。

例:你的網頁將有一個鏈接到「/MyCsvDownload.ashx?CompanyID=11」

你的項目將有一個助手類定義聲明WriteColumnHeaders和AddData靜態方法,並用代碼MyCsvDownload.ashx像這樣:

public class MyCsvDownload : IHttpHandler 
{ 
    public void ProcessRequest(HttpContext context) 
    { 
     var companyId = int.Parse(context.Request.QueryString["CompanyID"]); 

     string companyName; 
     ItemList list; 

     // TODO: Load company name and items from Company ID. 

     string attachment = string.Format("attachment; filename={0}_OutPut.csv", companyName); 

     context.Response.AddHeader("content-disposition", attachment); 
     context.Response.ContentType = "text/csv"; 
     context.Response.AddHeader("Pragma", "public"); 

     StringBuilder stringBuilder = new StringBuilder(); 

     HelperClass.WriteColumnName("Column1,Column2,Column3", stringBuilder); 
     context.Response.Write(stringBuilder.ToString()); 
     context.Response.Write(Environment.NewLine); 
     stringBuilder.Clear(); 

     foreach (Item i in list.Items) 
     { 
      HelperClass.AddData(i.TaxCodeValue.ToString(), stringBuilder); 
      HelperClass.AddData(i.Description.ToString(), stringBuilder); 
      HelperClass.AddData(i.Description.ToString(), stringBuilder); 

      context.Response.Write(stringBuilder.ToString()); 
      context.Response.Write(Environment.NewLine); 
      stringBuilder.Clear(); 
     } 

     context.Response.Flush(); 
    } 

    public bool IsReusable 
    { 
     get 
     { 
      return false; 
     } 
    } 
}