C# – Server cannot append header after HTTP headers have been sent c# excel inline

cexcel

I have this problem for trying to return a excel inline response.

I searched all through the help coding pages for answers to this and can not find something that works yet.

I made a simplified example of what I am doing below. This issue always happen.

Error in this line:

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

Code behind:

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)
    {
    }
}   

Best Answer

Yeah, you can't do that. In your PleaseWait method, you're calling Response.Flush. That sends the currently buffered output, along with the HTTP headers. HTTP headers are always sent before the other response data, so you're out of luck.

The usual way to do this is to have a separate PleaseWait page, which does a timed redirect to the actual file (which then only sends the file data along with the proper headers).

The basic issue is that HTTP is "Single request, single response". You're trying to return two responses to a single request, and that simply is not possible over pure HTTP (sadly; there are HTTP-like protocols that allow this, but they aren't really supported in browsers - it's a great boost to performance when you can send 20 files at once, rather than in 20 separate requests).

Related Topic