I have an app that needs to read a PDF file from the file system and then write it out to the user. The PDF is 183KB and seems to work perfectly. When I use the code at the bottom the browser gets a file 224KB and I get a message from Acrobat Reader saying the file is damaged and cannot be repaired.
Here is my code (I've also tried using File.ReadAllBytes(), but I get the same thing):
using (FileStream fs = File.OpenRead(path))
{
int length = (int)fs.Length;
byte[] buffer;
using (BinaryReader br = new BinaryReader(fs))
{
buffer = br.ReadBytes(length);
}
Response.Clear();
Response.Buffer = true;
Response.AddHeader("content-disposition", String.Format("attachment;filename={0}", Path.GetFileName(path)));
Response.ContentType = "application/" + Path.GetExtension(path).Substring(1);
Response.BinaryWrite(buffer);
}
Just for future reference, as stated in this blog post: http://blogs.msdn.com/b/aspnetue/archive/2010/05/25/response-end-response-close-and-how-customer-feedback-helps-us-improve-msdn-documentation.aspx
It is not recommended to call
Response.Close()
orResponse.End()
- instead useCompleteRequest()
.Your code would look somewhat like this:
In my MVC application, I have enabled gzip compression for all responses. If you are reading this binary write from an ajax call with gzipped responses, you are getting the gzipped bytearray rather than original bytearray that you need to work with.
}
" var blob = new Blob([response.data], { type: type }); " This will give you that invalid/corrupt file that you are trying to open when you turn that byte array into a file in your javascript if you don't uncompress it first.
To fix this, you have a choice to either prevent gzipping this binary data so that you can properly turn it into the file that you are downloading, or you have to decompress that gzipped data in your javascript code before you turn it into a file.
This works for us. We create PDFs from SQL Reporting Services.
Try adding
Response.End();
after the call to Response.BinaryWrite().
You may inadvertently be sending other content back after Response.BinaryWrite which may confuse the browser. Response.End will ensure that that the browser only gets what you really intend.