将gridview导出到excel文件时,Response.End()会生成错误

时间:2013-02-18 17:35:23

标签: c# asp.net gridview export-to-excel

我有这段代码:

protected void ibtGenerateReport_Click(object sender, ImageClickEventArgs e)
{
    string filename = "report.xls";             

    StringWriter stringWriter = new StringWriter();
    HtmlTextWriter htmlWrite = new HtmlTextWriter(stringWriter);
    DataGrid DataGrd = new DataGrid();            
    DataGrd.DataSource = odsLSRAudit;
    DataGrd.DataBind();

    DataGrd.RenderControl(htmlWrite);            

    System.IO.StreamWriter vw = new System.IO.StreamWriter(filename, true);
    stringWriter.ToString().Normalize();
    vw.Write(stringWriter.ToString());
    vw.Flush();
    vw.Close();
    WriteAttachment(filename, "application/vnd.ms-excel", stringWriter.ToString());           
}

public static void WriteAttachment(string FileName, string FileType, string content)
{
    HttpResponse Response = System.Web.HttpContext.Current.Response;
    Response.ClearHeaders();
    Response.AppendHeader("Content-Disposition", "attachment; filename=" + FileName);
    Response.ContentType = FileType;
    Response.Write(content);            
    Response.End();
}

Response.End()给出了以下错误:

Microsoft JScript runtime error: Sys.WebForms.PageRequestManagerParserErrorException: The message received from the server could not be parsed. Common causes for this error are when the response is modified by calls to Response.Write(), response filters, HttpModules, or server trace is enabled. Details: Error parsing near '<table cellspacing="'.

我可以看到Response.Write(content)有正确的信息。但除上述错误外,不会出现“保存/打开”对话框。

我正在使用UpdatePanels。

5 个答案:

答案 0 :(得分:26)

将此添加到您的Page_Load()方法

假设ibtGenerateReport是你的按钮

protected void Page_Load(object sender, EventArgs e) {
   ScriptManager scriptManager = ScriptManager.GetCurrent(this.Page);
   scriptManager.RegisterPostBackControl(this.ibtGenerateReport);
   //Further code goes here....
}

<强>解释

UpdatePanel控件使用异步回发来控制页面的哪些部分被渲染。它使用客户端上的一大堆JavaScript和服务器上的一大堆C#来实现这一点。这是使用客户端上的JavaScript可以理解的特殊格式呈现的。如果通过在页面的渲染阶段之外渲染事物来搞乱格式,则格式将被搞砸。

为什么我要继续获取PageRequestManagerParserErrorException?

那么,您可能正在执行错误消息中提到的事情之一。以下是最常见的原因以及它们不起作用的原因:

调用Response.Write(): 通过直接调用Response.Write(),您将绕过ASP.NET控件的正常呈现机制。您编写的位将直接发送给客户端而无需进一步处理。

响应过滤器/ HttpModules: 与Response.Write()类似,它们可以以UpdatePanel不知道的方式更改呈现。

已启用服务器跟踪: Trace是使用Response.Write()有效写出的,因此会混淆我们用于UpdatePanel的特殊格式。

调用Server.Transfer(): 不幸的是,没有办法检测到Server.Transfer()被调用了。这意味着当有人调用Server.Transfer()时,UpdatePanel无法执行任何智能操作。发送回客户端的响应是您转移到的页面的HTML标记。由于它的HTML而不是特殊格式,因此无法解析,并且您收到错误。

<强>解决方案: 避免解析错误的一种方法是通过调用 ScriptManager.RegisterPostBackControl()

来执行常规回发而不是异步回发

请参阅Ellon Lipton博客的完整说明和其他解决方案 here

答案 1 :(得分:4)

更改Response.End由此:

Response.Flush();
HttpContext.Current.ApplicationInstance.CompleteRequest();

Response.End是一种不好的做法,它会中止线程以绕过http请求生命周期中的其余操作,并抛出异常。

答案 2 :(得分:0)

您是否在向响应写入任何内容之前尝试过Response.Clear(),然后在结束响应之前尝试使用Response.Flush()?

此外,在Response.End()中传递true值永远不会受到伤害,以避免重定向上的HTTP异常错误。只需确保代码隐藏的其余部分没有进行您不想要的其他处理。

答案 3 :(得分:0)

由于您尝试通过UpdatePanels执行此操作,因此您应该尝试使用jQuery Ajax并在页面加载事件的单独页面中编写此代码,以便在调用此页面的请求时获取该文件。新响应实际上是删除了需要解析的信息,作为对先前更新面板请求的响应。

答案 4 :(得分:0)

此代码与您的aspx中的某些 UpdatePanel / AJAX 相冲突。

尝试在你的aspx中写这个:

Code - 应该有用! :&#39)

相关问题