0

I have observed that when a file is downloaded with the following code:

HttpContext.Current.Response.ContentType = "application/pdf";
HttpContext.Current.Response.AddHeader("content-disposition", "attachment;filename=~/test.pdf");
HttpContext.Current.Response.WriteFile("~/test.pdf");
HttpContext.Current.ApplicationInstance.CompleteRequest();

We get a file larger than if the code below is used:

HttpContext.Current.Response.ContentType = "application/pdf";
HttpContext.Current.Response.AddHeader("content-disposition", "attachment;filename=~/test.pdf");
HttpContext.Current.Response.WriteFile("~/test.pdf");
HttpContext.Current.Response.End();

The larger size is because in the first case is added, after the end of the file, the source code of the page from which the file is downloaded. So all downloaded files are increased with a fixed number of bytes equal to the length in bytes of source code. In the case of a PDF, when open it with Adobe Reader, those extra bytes are interpreted as a change and when close prompted to save the changes, after which the pdf recovers its smaller size. If the files are compared with an hexdecimal editor warns that are identical but of different sizes and can be seen at the end, after the EOF mark, the bytes of page source code.

The same is true if, instead of a physical file, use a MemoryStream and send the array of bytes by Response.BinaryWrite(), for example.

What can be the cause of this behavior and how can it be corrected?

jalbala
  • 1
  • 3

2 Answers2

0

I found the solution. With Response.SupressContent() the html added after the EOF mark is suppressed and the file pdf is identical to the source:

HttpContext.Current.Response.ContentType = "application/pdf";
HttpContext.Current.Response.AddHeader("content-disposition", "attachment;filename=~/test.pdf");
HttpContext.Current.Response.WriteFile("~/test.pdf");
Response.Flush();
Response.SuppressContent = true;
HttpContext.Current.ApplicationInstance.CompleteRequest();
jalbala
  • 1
  • 3
0

To avoid rendering the page when using HttpApplication.CompleteRequest(), you can set Page.Visible to false. This is better than HttpResopnse.SuppressContent because it actually avoids rendering the content in the first place instead of executing it.

I think that avoiding Flush() is also recommended because that prevents an asynchronous flush.

This code is written with the assumption that it is in a subclass of System.Web.UI.Page:

Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;filename=~/test.pdf");
Response.WriteFile("~/test.pdf");
Response.SuppressContent = true;
Visible = false;
Context.ApplicationInstance.CompleteRequest();
binki
  • 7,754
  • 5
  • 64
  • 110