2012-07-10 72 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; 
     } 
    } 
}