C# Response.End() 将gridview 导出到excel 文件时产生错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14942085/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 13:29:55  来源:igfitidea点击:

Response.End() generates an error when exporting gridview to excel file

c#asp.netgridviewexport-to-excel

提问by Somebody

I have this code:

我有这个代码:

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();
}

But the Response.End()gives me the below error:

但是这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="'.

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="'.

The Response.Write(content)has the correct information as I can see. But no Save/Open dialog box appear, besides the above error.

Response.Write(content)正如我所见,有正确的信息。但是没有出现保存/打开对话框,除了上面的错误。

I'm using UpdatePanels.

我正在使用更新面板。

采纳答案by feco

Add this to your Page_Load() method

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

Assuming ibtGenerateReport is your button

假设 ibtGenerateReport 是你的按钮

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

Explanation:

解释:

The UpdatePanel control uses asynchronous postbacks to control which parts of the page get rendered. It does this using a whole bunch of JavaScript on the client and a whole bunch of C# on the server. This is rendered out using a special format that the JavaScript on the client can understand. If you mess with the format by rendering things outside of the render phase of the page, the format will be messed up.

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

Why do I keeping getting a PageRequestManagerParserErrorException?

为什么我不断收到 PageRequestManagerParserErrorException?

Well, chances are you're doing one of the things mentioned in the error message. Here are the most common reasons and why they don't work:

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

Calls to Response.Write():By calling Response.Write() directly you are bypassing the normal rendering mechanism of ASP.NET controls. The bits you write are going straight out to the client without further processing.

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

Response filters /HttpModules :Similar to Response.Write(), they can change the rendering in such a way that the UpdatePanel won't know.

响应过滤器 /HttpModules :与 Response.Write() 类似,它们可以以更新面板不知道的方式更改渲染。

Server trace is enabled:Trace is effectively written out using Response.Write(), and as such messes up the special format that we use for UpdatePanel.

启用服务器跟踪:使用 Response.Write() 有效地写出跟踪,因此弄乱了我们用于 UpdatePanel 的特殊格式。

Calls to Server.Transfer():Unfortunately, there's no way to detect that Server.Transfer() was called. This means that UpdatePanel can't do anything intelligent when someone calls Server.Transfer(). The response sent back to the client is the HTML markup from the page to which you transferred. Since its HTML and not the special format, it can't be parsed, and you get the error.

调用 Server.Transfer():不幸的是,无法检测到 Server.Transfer() 被调用。这意味着当有人调用 Server.Transfer() 时,UpdatePanel 不能做任何智能的事情。发送回客户端的响应是来自您传输到的页面的 HTML 标记。由于它是 HTML 而不是特殊格式,因此无法解析它,并且您会收到错误消息。

Solution:One way to avoid the parse error is to do a regular postback instead of an asynchronous postback by calling ScriptManager.RegisterPostBackControl()

解决方案:避免解析错误的一种方法是通过调用ScriptManager.RegisterPostBackControl()执行常规回发而不是异步回发

Please refer to the complete Explanation and other solutions from Ellon Lipton's blog here

在此处参考Ellon Lipton 博客中的完整说明和其他解决方案

回答by Ripside

Have you tried a Response.Clear() prior to writing anything to the response, then a Response.Flush() before ending the response?

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

Also, it never hurts to pass a value of true in Response.End(), to avoid HTTP exception errors on a redirect. Just make sure the rest of the code-behind isn't doing additional processing you don't want.

此外,在 Response.End() 中传递 true 值也没有什么坏处,以避免重定向时出现 HTTP 异常错误。只要确保其余的代码隐藏没有进行您不想要的额外处理。

回答by Carlos Grappa

Change Response.End by this:

更改 Response.End 为:

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

Response.End is a bad practice, it aborts the thread to bypass the rest of the operations in the http request lifecycle and it throws an exception.

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

回答by Anubhav Ranjan

Since you are trying to do it through UpdatePanels, you should try using jQuery Ajax and write this code in a separate page in the page load event to get the file when you invoke the request to this page. The new response is actually removing the information required to be parsed as a response to the previous update panel request.

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

回答by SBelim

This code is conflicting some UpdatePanel/AJAXin your aspx.

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

Try writing this in your aspx:

尝试在你的 aspx 中写这个:

Code- which should work! :')

代码- 这应该有效!:')