2

So I have a button inside my gridview. If the user clicks on the button a rowcommand is send and a pdf file is downloaded / written to the response.

Code

HttpResponse httpResponse = Response;
httpResponse.Clear();

httpResponse.ContentType = "application/pdf";
httpResponse.AddHeader("content-disposition", $"attachment;filename={rowData.Pod.fileName}");
httpResponse.Output.Write(bytes);

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

For some reason I always get Server cannot set content type after HTTP headers have been sent. when tried to download the file. Now the gridview is in a updatepanel but that should not be a problem since other buttons for downloading work.

I have also tried to send the buffer to true before I did the file download but that did not change it.

EDIT

The problem was that there was still an async postback that I had setup on the 'selectedindexchanged' of the gridview to display a modal. Is there any way I can work around this? When I change the trigger the whole page reloads before showing the modal and also resprings. The file downloads after changing it to postback instead of asyncpostback

Dan Atkinson
  • 11,391
  • 14
  • 81
  • 114
Florian Schaal
  • 2,586
  • 3
  • 39
  • 59

2 Answers2

1

I had an issue that was extremely similar to this. I had a button inside a ListView control that was trying to print a pdf report. After extensive research I found a very simple solution.

Add OnInit="btnPrint_Init" to the button on the front of the page and then add the following to the code behind (change the name of the button to suit your needs):

    protected void btnPrint_Init(object sender, EventArgs e)
    {
        Button btnPrint = (Button)sender;
        ScriptManager.GetCurrent(this).RegisterPostBackControl(btnPrint);
    }
Allen
  • 165
  • 1
  • 2
  • 14
0

Probably, Response.Buffer is false.

You should write the content after writing the headers.

httpResponse.ContentType = "application/pdf";
httpResponse.AddHeader("content-disposition", $"attachment;filename={rowData.Pod.fileName}");
httpResponse.Output.Write(bytes);

Actually, you can instead set a JavaScript command to those buttons requesting an http handler which is the best practice for downloading a file.

For security reasons you can create a guid and put the guid to session items for each row (having the file id as the value) and then send that guid to the http handler and retrieve the file id from session and response binary write the file

Oguz Ozgul
  • 6,809
  • 1
  • 14
  • 26
  • Sorry that was a test on my side. I have edited my awnser the same error occurred when changing it. When should I set the buffer to true? – Florian Schaal Nov 05 '15 at 14:18
  • I don't know why the Response.Buffer is false because by default it is true. The request from the UpdatePanel may be causing the issue. Can you first check the value of Response.Buffer by breaking on HttpResponse.Clear() ? – Oguz Ozgul Nov 05 '15 at 14:22
  • Check [this](http://stackoverflow.com/questions/10014920/response-write-and-updatepanel) – Oguz Ozgul Nov 05 '15 at 14:23
  • I have check it while debugging and its true till the end. I will give the async trigger a try – Florian Schaal Nov 05 '15 at 14:24
  • This is not possible in the current setup because the button id is generated on runtime so the control id is unknown. – Florian Schaal Nov 05 '15 at 14:31
  • The problem was that there was still an async postback that I had setup on the 'selectedindexchanged' of the gridview to display a modal. Is there any way I can work around this? When I change the trigger the whole page reloads before showing the modal – Florian Schaal Nov 05 '15 at 14:37
  • You can instead set a JavaScript command to those buttons requesting an http handler which is the best practice for downloading a file. For security reasons you can create a guid and put the guid to session items for each row and then send that guid to the handler and retrieve the file id from session and response binary write the file – Oguz Ozgul Nov 05 '15 at 17:13