HTTP标头发送后,服务器无法追加标头c#excel内联

我有这个问题试图返回一个Excel内联响应。

我search了所有帮助编码页面的答案,并找不到有效的东西。

我在下面做了一个简单的例子。 这个问题总是发生。

错误在这一行:

Line 56: Response.AddHeader("content-disposition", 

代码后面:

 public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { PleaseWait(); Call(); } protected void Call() { strSql = "SELECT * FROM ....... ; "; SqlCommand cmd = new SqlCommand(strSql); DataTable dt = GetData(cmd); GridView GridView1 = new GridView(); GridView1.AllowPaging = false; GridView1.DataSource = dt; GridView1.DataBind(); Response.Clear(); Response.Buffer = true; Response.BufferOutput = true; Response.ClearHeaders(); Response.AddHeader("content-disposition", "attachment;filename= "Output.xls"); Response.Charset = ""; Response.ContentType = "application/vnd.ms-excel"; StringWriter sw = new StringWriter(); HtmlTextWriter hw = new HtmlTextWriter(sw); for (int i = 0; i < GridView1.Rows.Count; i++) { GridView1.Rows[i].Attributes.Add("class", "textmode"); } GridView1.RenderControl(hw); string style = @"<style> .textmode { mso-number-format:\@; } </style>"; Response.Write(style); Response.Output.Write(sw.ToString()); Response.Flush(); Response.End(); } protected void PleaseWait() { this.Response.Write("<meta http-equiv=X-UA-Compatible content=IE=8>"); this.Response.Write(@"<style type=text/css media=all>"); this.Response.Write(@".loading"); this.Response.Write(@"{"); this.Response.Write(@"text-align: center;"); this.Response.Write(@"padding-top: 30px;"); this.Response.Write(@"border-width: 1px solid #000;"); this.Response.Write(@"width: 300px;"); this.Response.Write(@"height: 100px;"); this.Response.Write(@"-ms-filter: alpha(opacity=90);"); this.Response.Write(@"-ms-opacity: 0.90;"); this.Response.Write(@"border-style: solid;"); this.Response.Write(@"background-color: #FFFFFF;"); this.Response.Write(@"position: absolute;"); this.Response.Write(@"font-family: Trebuchet MS;"); this.Response.Write(@"font-size: small;"); this.Response.Write(@"position: absolute;"); this.Response.Write(@"top: 0;"); this.Response.Write(@"bottom: 0;"); this.Response.Write(@"left: 0;"); this.Response.Write(@"right: 0;"); this.Response.Write(@"margin: auto;"); this.Response.Write(@"display: block;"); this.Response.Write(@"background: url('images/wait01.gif') no-repeat center;"); this.Response.Write(@"}"); this.Response.Write(@"</style>"); this.Response.Write(@"<div id=mydiv class=loading>&nbsp;</div>"); this.Response.Write(@"<script>mydiv.innerText = '';"); this.Response.Write(@"</script>"); this.Response.Write(@"<script language=javascript>;"); this.Response.Write(@"var dots = 0;"); this.Response.Write(@"var dotmax = 10;"); this.Response.Write(@"function ShowWait()"); this.Response.Write(@"{"); this.Response.Write(@"var output;"); this.Response.Write(@"output = 'Wait...';"); this.Response.Write(@"dots++;"); this.Response.Write(@"if(dots>=dotmax)dots=1;"); this.Response.Write(@"for(var x = 0;"); this.Response.Write(@"x < dots;x++)"); this.Response.Write(@"{"); this.Response.Write(@"output += '.';"); this.Response.Write(@"}"); this.Response.Write(@"mydiv.innerText = output;"); this.Response.Write(@"}"); this.Response.Write(@"function StartShowWait()"); this.Response.Write(@"{"); this.Response.Write(@"mydiv.style.visibility = 'visible'; "); this.Response.Write(@"window.setInterval('ShowWait()',1500);"); this.Response.Write(@"}"); this.Response.Write(@"function HideWait()"); this.Response.Write(@"{"); this.Response.Write(@"mydiv.style.visibility = 'hidden';"); this.Response.Write(@"window.clearInterval();"); this.Response.Write(@"}"); this.Response.Write(@"StartShowWait();"); this.Response.Write(@"</script>"); this.Response.Flush(); Thread.Sleep(500); } private DataTable GetData(SqlCommand cmd) { DataTable dt = new DataTable(); String strConnString = System.Configuration.ConfigurationManager. ConnectionStrings["conn"].ConnectionString; SqlConnection con = new SqlConnection(strConnString); SqlDataAdapter sda = new SqlDataAdapter(); cmd.CommandType = CommandType.Text; cmd.Connection = con; try { con.Open(); sda.SelectCommand = cmd; sda.Fill(dt); return dt; } catch (Exception ex) { throw ex; } finally { con.Close(); sda.Dispose(); con.Dispose(); } } public override void VerifyRenderingInServerForm(Control control) { } } 

是的,你不能这样做。 在您的PleaseWait方法中,您正在调用Response.Flush 。 这发送当前缓冲的输出,以及HTTP头。 HTTP头始终在其他响应数据之前发送,所以你运气不好。

通常的做法是有一个单独的PleaseWait页面,它将定时redirect到实际的文件(然后只发送文件数据和适当的头文件)。

基本问题是HTTP是“单一请求,单一响应”。 你试图对一个请求返回两个响应,而这纯粹是不可能通过纯HTTP进行的(可悲的是,有类似于HTTP的协议允许这样做,但是浏览器并不支持它们,这对于性能可以一次发送20个文件,而不是20个独立的请求)。