PDF file sometime being displayed as garbage - asp.net

I am having a user who is reporting that files are being displayed as raw data in his browser. He uses Internet Explorer.
The files are being served via a .ashx handler file and it has been working until.
This is the relevant part of my .ashx handler:
context.Response.Clear()
context.Response.AppendHeader("Content-Disposition", "attachment; filename=" + name)
context.Response.AppendHeader("Content-Length", size.ToString)
context.Response.ContentType = "application/pdf"
context.Response.TransmitFile(fullname)
context.Response.Flush()
HttpContext.Current.ApplicationInstance.CompleteRequest()
Can anyone figure something out of this screenshot?
Update: this behaviour appears on Windows 10 when running either IE 11 or Edge and only the second time a file is being opened. It happens for both .pdf and .docx files.

This is the code I use to stream PDFs to a client. It works in IE 11. The main difference is that I am using BinaryWrite which based on your code, you may not want to do..
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.AddHeader("Content-Type", "application/pdf");
HttpContext.Current.Response.AddHeader("Content-Disposition", "inline; filename=" + fileName + ".pdf");
HttpContext.Current.Response.BinaryWrite(bytes);
HttpContext.Current.Response.End();
There might be a solution here
I'll like this as well just in case..
According to this thread, it could be as simple as replacing Response.Close with Response.End (or in your case.. adding)

I finally found the answer myself - it had to do with the HTTP header content-length which i mistakenly submitted with a value exactly 1byte too large.
This caused the strange behavior in only IE/Edge and only Windows 10 as described in the OP.

I had the same problem with an aspx page that transmits file to browser in Page_Load event handler.
My mistake was an absense of
Response.End();
method call. When I added this line the problem has gone.

Related

HTTPS content-disposition attachment

Symptoms are very like C# BinaryWrite over SSL but my code already complies with all of the proposed solutions. This behaviour was manifest on Edge, IE11 and Chrome at the time of writing. Code that worked fine over HTTP broke when delivered over HTTPS.
private void RenderPdfToResponse(bool asDownload, byte[] documentBytes)
{
Response.BufferOutput = true;
Response.ClearContent();
Response.ClearHeaders();
Response.AddHeader("Cache-control", "no-store");
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Length", documentBytes.Length.ToString());
if (asDownload)
Response.AddHeader("Content-Disposition",
string.Format("attachment; filename=export{0:yyyyMMddHHmmss}.pdf", DateTime.UtcNow));
Response.BinaryWrite(documentBytes);
Response.Flush();
HttpContext.Current.ApplicationInstance.CompleteRequest();
}
The problem is at the browser. Delivered binary content that should be saved into a file is instead rendered in the browser window. Interception with debug tools and saving into a file allows verification that the delivered bytes form a valid PDF.
Given that all the suggestions of the referenced question are already in effect, and the problem is browser behaviour, what options remain?
Consulting https://www.rfc-editor.org/rfc/rfc6266 we find that the filename portion is optional. Experimentally specifying
Response.AddHeader("Content-Disposition", "attachment");
causes all major browsers to pop a Save As dialog with the name export-pdf.pdf which is apparently derived from the name of the ASPX file and the mime type.
At this point I was asked to ship. I hope someone finds this helpful.

Exception While Downloading PDF file in asp.net

I am downloading a file in asp.net
Here is the code
Response.ContentType = "Application/.pdf";
Response.AppendHeader("Content-Disposition", "attachment; filename="+extractFileName+".pdf");
Response.TransmitFile(extractFilePath);
Response.Flush();
Response.End();
The file is downloading properly but at Response.End(); it throws following exception:
{Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack.}
The provided message is not an exception, but a message indicating that it cannot show you the error due to optimizations performed by the compiler, and due to the current code location.
Try removing the response.End and see if it will allow you to see the error.
There are several issues.
I think the main issue will be that you're using extractFileName for both the name that will be used to open/save the file at the browser, and also as the physical name of the file to transmit. So you are either using a full path for the content-disposition when it needs just a filename... or you are not giving a full path for the transmit.
You are also using an incorrect MIME Type for the PDF, which should be application/pdf
(And you are also include .pdf at the end of the extractFileName, so I presume the variable doesn't already include the extension?)
If extractFileName is the full physical path to the file (including extension), then try replacing...
Response.AppendHeader("Content-Disposition", "attachment; filename="+extractFileName+".pdf");
with...
string contentFileName = System.IO.Path.GetFileName(extractFileName);
Response.AppendHeader("Content-Disposition", "attachment; filename="+contentFileName);
TransmitFile() cannot be used for files outside the directory structure of your website. In that case use another way to write the file to the Response.
Remark:
If the filename contains multiple points (.) or characters like comma (,), some browsers will mess up the filename. Add extra quotes to the filename to avoid problems.
Response.AppendHeader("content-disposition", "attachment; filename=\"" + file + "\";");

Prompting user for download, IE sets the filename as the .aspx name ("Would you like to download SomePage.aspx?fileID=12345")

I am at a loss here. I am trying to transmit a file on the local intranet site. When I get a download prompt in IE11, it says:
Do you want to open or save "SomePage.aspx?fileID=12345"? [open] [save] [cancel]
Instead of..
Do you want to open or save "Document.pdf"? [open] [save] [cancel]
It works perfectly fine on Chrome. The file gets downloaded with the correct filename. But for some reason, IE isn't setting the name and instead uses the ASPX name.
The code is rather straightforward:
testFile = New System.IO.FileInfo("\\someshare\somefolder$\Document.pdf")
Response.Clear()
Response.AddHeader("Content-Disposition", "attachment; filename=" & testFile.Name)
Response.AddHeader("Content-Length", testFile.Length.ToString())
Response.ContentType = "application/octet-stream"
Response.TransmitFile(testFile.FullName)
I've tried a number of different header options and the MIME type makes no difference.
Does anyone have a clue why this would be happening?
Notes: Not HTTPS. It is not limited to PDF, same happens with .TIF, .DOC, and every other format I've tested.
EDIT: Have also tried Response.WriteFile as well as Response.BinaryWrite .. same thing each time.
EDIT2: Simplified everything down to a single button on a completely blank page.
You should have quote marks around the file name. See 19.5.1 on http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html
i.e.
Content-Disposition: attachment; filename="fname.ext"
so...
Response.AddHeader("Content-Disposition", String.Format("attachment; filename=""{0}""", testFile.Name))
Unfortunately I have not been able to test if this solves your issue as I don't have access to IE11 at the moment.
So I know this question is older, but the solution I finally came up with to this problem is to add the following two lines to my code.
Response.SuppressContent = True
and
HttpContext.Current.ApplicationInstance.CompleteRequest()
You have said in previous comments that you have tried the CompleteRequest command to no avail.
As a note, I am not 100% certain to the logistics of the Response.SuppressContent() command.
The documentation says that it indicates "whether to send HTTP content to the client". This seems counter intuitive to the process of sending the request body back to the client, however, it appears to only suppress the parts of the response that include any HTML.
It seems that the partial or incomplete HTML is what causes the filename to appear as the page name regardless of the headers set and sent. Stripping this out should cause the file to download properly.
Interestingly, this solution is actually born out of a secondary issue where once I was able to export the file using ClosedXML, i was receiving messages when opening the document that there were errors than excel would try to fix.
Response.SuppressContent actually fixed that as well. Hope this helps or at least points you in the right direction.

How do I send a binary blob to a client browser?

Pardon the dumb newbie question here; web programming isn't my forte... (blush)
I have an aspx page running on a web server. I have a blob (byte array) containing any kind of binary file, plus a file name.
I would like to push this file to be downloaded through the browser onto the client, and opened using whatever application is default for this file type. I really don't want to save the blob as a file on the server; that will leave a terrible housekeeping mess that I just don't want to think about.
I did try googling this question, but I guess I'm using the wrong keywords.
This really should be obvious how to do it, but I'm having no joy.
What is the trick?
Thanks!
Response.BinaryWrite(byteArray);
You should also set the content type
Response.ContentType = "application/pdf";
But that will be based on your file type.
And the file name (and everything together) is done like this
Response.AddHeader("content-disposition",
String.Format("attachment;filename={0}", fileName));
Response.ContentType = "application/pdf";
Response.BinaryWrite(byteArray);
First, you have to know the mime type. Once you know that, you can set the Response.ContentType property. After that, just use Response.BinaryWrite(). If you don't first set the ContentType property, the client will have almost no chance of opening the file correctly.

Response Content type as CSV

I need to send a CSV file in HTTP response. How can I set the output response as CSV format?
This is not working:
Response.ContentType = "application/CSV";
Using text/csv is the most appropriate type.
You should also consider adding a Content-Disposition header to the response. Often a text/csv will be loaded by a Internet Explorer directly into a hosted instance of Excel. This may or may not be a desirable result.
Response.AddHeader("Content-Disposition", "attachment;filename=myfilename.csv");
The above will cause a file "Save as" dialog to appear which may be what you intend.
MIME type of the CSV is text/csv according to RFC 4180.
Use text/csv as the content type.
Over the years I've been honing a perfect set of headers for this that work brilliantly in all browsers that I know of
// these headers avoid IE problems when using https:
// see http://support.microsoft.com/kb/812935
header("Cache-Control: must-revalidate");
header("Pragma: must-revalidate");
header("Content-type: application/vnd.ms-excel");
header("Content-disposition: attachment; filename=$filename.csv");
Try one of these other mime-types (from here: http://filext.com/file-extension/CSV )
text/comma-separated-values
text/csv
application/csv
application/excel
application/vnd.ms-excel
application/vnd.msexcel
Also, the mime-type might be case sensitive...
Just Use like that
Response.Clear();
Response.ContentType = "application/CSV";
Response.AddHeader("content-disposition", "attachment; filename=\"" + filename + ".csv\"");
Response.Write(t.ToString());
Response.End();
In ASP.net MVC, you can use a FileContentResult and the File method:
public FileContentResult DownloadManifest() {
byte[] csvData = getCsvData();
return File(csvData, "text/csv", "filename.csv");
}
I have found that the problem with IE is that it sniffs the return data and makes up its own mind about what content-type it thinks it has been sent. There are a number of side effect that this causes, such as always openning a saveAs dialog for text files because you are using compression of data trasnferes. The solution is (in php code)......
header('X-Content-Type-Options: nosniff');
I suggest to insert an '/' character in front of 'myfilename.cvs'
Response.AddHeader("Content-Disposition", "attachment;filename=/myfilename.csv");
I hope you get better results.
Setting the content type and the content disposition as described above produces wildly varying results with different browsers:
IE8: SaveAs dialog as desired, and Excel as the default app. 100% good.
Firefox: SaveAs dialog does show up, but Firefox has no idea it is a spreadsheet. Suggests opening it with Visual Studio! 50% good
Chrome: the hints are fully ignored. The CSV data is shown in the browser. 0% good.
Of course in all of these cases I'm referring to the browsers as they come out of they box, with no customization of the mime/application mappings.
For C# MVC 4.5 you need to do like this:
Response.Clear();
Response.ContentType = "application/CSV";
Response.AddHeader("content-disposition", "attachment; filename=\"" + fileName + ".csv\"");
Response.Write(dataNeedToPrint);
Response.End();
return new EmptyResult(); //this line is important else it will not work.

Resources