Trying to stream a PDF file with asp.net is producing a "damaged file"

asp.net, filestream

Solution

Here is a method I use. This passes back an attachment, so IE produces an Open/Save dialog. I also happen to know that the files will not be larger than 1M, so I'm sure there's a cleaner way to do this.

I had a similar problem with PDFs, and I realized that I absolutely had to use Binary streams and ReadBytes. Anything with strings messed it up.

Stream stream = GetStream(); // Assuming you have a method that does this.
BinaryReader reader = new BinaryReader(stream);

HttpResponse response = HttpContext.Current.Response;
response.ContentType = "application/pdf";
response.AddHeader("Content-Disposition", "attachment; filename=file.pdf");
response.ClearContent();
response.OutputStream.Write(reader.ReadBytes(1000000), 0, 1000000);

// End the response to prevent further work by the page processor.
response.End();

Problem

In one of my asp.net web applications I need to hide the location of a pdf file being served to the users. Thus, I am writing a method that retrieves its binary content from its location on a CMS system and then flushes a byte array to the web user. I'm getting, unfortunately, an error when downloading the stream: "Could not open the file because it is damadged" (or something similar to that, when opening the file in adobe reader). Question 1: what am I doing wrong? Question 2: can I download large files using this approach? ``` private void StreamFile(IItem documentItem) { //CMS vendor specific API BinaryContent itemBinaryContent = documentItem.getBinaryContent(); //Plain old .NET Stream fileStream = itemBinaryContent.getContentStream(); var len = itemBinaryContent.getContentLength(); SendStream(fileStream, len, itemBinaryContent.getContentType()); } private void SendStream(Stream stream, int contentLen, string contentType) { Response.ClearContent(); Response.ContentType = contentType; Response.AppendHeader("content-Disposition", string.Format("inline;filename=file.pdf")); Response.AppendHeader("content-length", contentLen.ToString()); var bytes = new byte[contentLen]; stream.Read(bytes, 0, contentLen); stream.Close(); Response.BinaryWrite(bytes); Response.Flush(); } ```

Original source