PDF wrong error in IE6 and IE7 with https - asp.net

Response.Write("<script language=\"javascript\">window.open( with https and pdf
What we do in a Asp.Net 1.1.4332 application is the following:
a button triggers a server event that does some processing and puts the data in a session object after that the following code is executed :
string page = Request.ApplicationPath + "/ApkRapportPage.aspx";
Response.Write("<script language=\"javascript\">window.open('" + page + "','_new');</script>");
this opens a page that streams a pdf to the new browser window
basically with the following code ( I know stuff is missing here, but that doesn't really mater for the question)
byte[] pdfbytes = Convert.FromBase64String(rapportB64);
Response.ClearContent();
Response.ClearHeaders();
Response.Buffer = true;
Response.ContentType = GetContentType(format);
string header = GetContentDispostionHeader(fileName, format, type);
Response.AddHeader("Content-Disposition", header);
Response.BinaryWrite(pdfbytes);
Response.End();
Okay this code works !
Just not in IE6 and IE7 when using HTTPS
When using IE6 with HTTPS it results in a save-as dialog (not a pdf that opens in a browser)
When using IE7 with HTTPS it results in a blank screen
When using Firefox it works just fine
If I simulate the extra server side processing in the page_load to put the required data in the session and replace the button with a link that opens the same pdf generating page in a new window, the code works.
For the actual application it is not an option to get the required data before the button is clicked.
So I would really like to get the following code to work
string page = Request.ApplicationPath + "/ApkRapportPage.aspx";
Response.Write("<script language=\"javascript\">window.open('" + page + "','_new');</script>");
Questions:
Does anybody know why this code doesn't work in IE6 and IE7 when using HTTPS ?
What is needed to get the code to work ?
Extra info:
I tried not using response.write but
just a javascript window.open behind
the button, this has the same effect
when googling for pdf streaming, you can find a lot of people having
trouble with this, mostly they set
header lengths or other properties or
static file compression flags in IIS.
I am pretty confident I tried them
all.
Adobe acrobat reader settings, browser settings or any other client
side settings don't seem to be the
problem. Tested on different
machines, with http works, with https
it doesn't.
Switching between https and http might have something to do with this,
but when I set IE to tell me when I
am switching, no switching seems to
occur during testing.
When replacing the window.open part with a response.redirect then the code also works, just not in a new window
Any help would be greatly appreciated !
As requested the headers, as shown by Fiddler:
HTTP/1.1 200 OK
Server: Microsoft-IIS/5.1
Date: Thu, 05 Mar 2009 14:18:36 GMT
X-Powered-By: ASP.NET
X-AspNet-Version: 1.1.4322
Content-Disposition: Inline;filename=APKrapport.pdf
Cache-Control: private
Content-Type: application/pdf; charset=utf-8
Content-Length: 28307

Getting attachments to open the way you want has everything to do with the headers you send. If you locate to an .aspx page that you want to act as a dynamic PDF resource these HTTP headers become increasingly important.
This website states a number of reasons why it might not work in IE.
Set the content-type of the response to "application/pdf", ex. response.setContentType("application/pdf");
Add a dummy parameter on the end of the url, like:
http://x.y.z/DoGenCompStmt?filename=dummy.pdf
because IE ignores content-types, so you need to give it a hint, and the ".pdf" extension is an easy way.
Set the "content-length" on the response, otherwise the Acrobat Reader plugin may not work properly, ex. response.setContentLength(bos.size());
An additional thing that seems to help some IE browsers is to also have : response.setHeader("Content-Disposition", "inline;filename=somepdf.pdf");
EDIT: since you already tried all of the above i can only point you to the rfc for content disposition which to my knowledge is the only way to tell a browser how to deal with binary content.
EDIT: what would really help is to see the HTTP Headers it currently returns when you try to open the pdf in the browser. Fiddler does a great job at catching traffic

You'd be better off using a generic handler (.ASHX) to serve this sort of content, rather than trying to force a web-page to serve content other than HTML.

After a lot of trial and error I found a working solution, still not sure why the other code doesn't work.
This code works:
StringBuilder js = new StringBuilder("<script language=\"javascript\">");
js.Append("_window = window.open(\"\",'_new');");
js.Append("_window.document.open(\"application/pdf\");");
js.Append("_window.location.href = \"ApkRapportPage.aspx\";");
js.Append("_window.document.close();");
js.Append("</script>");
Response.Write(js.ToString());
Must have something to do with the mime type.
It has a problem though. When IE is set to show when you switch between HTTP and HTTPS this code will give that message twice. The following code doesn't switch but causes the page load of ApkRapportPage to be fired twice.
StringBuilder js = new StringBuilder("<script language=\"javascript\">");
js.Append("_window = window.open(\"ApkRapportPage.aspx\",'_new');");
js.Append("_window.document.open(\"application/pdf\");");
js.Append("_window.location.href = \"ApkRapportPage.aspx\";");
js.Append("_window.document.close();");
js.Append("</script>");
Response.Write(js.ToString());

If you are getting a blank page when trying to view a PDF inline in the IE7 browser and you are using Acrobat version 6. Update your Acrobat version to resolve problem.

Note that this problem is unrelated to HTTPS, the same problem (and the same fix) applies for HTTP.
The fix works because the problem with IE is that it doesn't display PDF in a script-opened window if the PDF is loaded at once. (Unknown why, but this is the core of the problem, and the fix.)

I notice that your returned content-type is hosed
"Content-Type: application/pdf; charset=utf-8"
When you stream the content to the aspx page ensure that you set the
Response.charset = ""

Related

Web form non-responsive after download

I'm working in ASP.NET (2.0) and we have a page where a user is able to select and download a series of files as a zip. I got this to work without undo difficulty by using the DotNetZip library (which is probably not relevant to the problem, but included for completeness.)
After the user checks which files they want to download, the page does a postback, and in the button click event handler, I use the following code:
Response.Clear();
Response.BufferOutput = false; // false = stream immediately
Response.ContentType = "application/zip";
Response.AddHeader("content-disposition", "filename=FileRequest.zip");
using (ZipFile zip = new ZipFile())
{
zip.AddFile(MapPath("/datafiles/fileToZip.pdf"), "");
zip.Save(Response.OutputStream);
}
Response.Close();
And this all seems to work great. The user clicks the button, a download window pops up, the user downloads the zip. All is good...
...until they decide they want to do something else on the page. The buttons in the form are no longer responsive. For instance, if I click the download button again, it does nothing. If I reload the page, I can repeat this behavior...it works once, then does nothing.
I'm not understanding why the browser doesn't send the new request. It's not "spinning" or otherwise acting busy. I thought that this might be a browser issue, but I've repeated it in both IE and Firefox, so it seems likely that it's something I'm not understanding. Strangely, it's only form submission elements that seem to be non-responsive. Javascript still works, and so do regular links.
So why is this happening, and how do I get around it?
The problem is likely down to you returning;
Response.ContentType = "application/zip";
Once this has been sent (along with the actual content), the browser would assume it has nothing left to do (I believe).
You probably should create a new window specifically for downloading the files by saving the file selection in a session parameter (or equivalent) and opening a popup window that has your download code in.
This will leave the parent page in a suitable state.
Content-disposition header seems to be a discouraged solution. But the same effect of ASP.NET forms not being responsive occurs if you use standard Redirect to a zip file.
I solved very similar problem (returning *.csv files by the server for download) using Tančev Saša's code in "Response.Redirect to new window" Q&A and it works great. Perhaps it might produce some popup warnings in some browsers, but I think this is how it's often done in download sites.

How can I get an asp.net mvc action to consistently deliver a file to the browser?

I'm building a little action to take an encrypted PDF file path, decrypt it, and deliver the resulting PDF to the browser.
My code works 100% of the time in Chrome and Firefox, but it works only 50% of the time in IE9.
When I follow the link in IE9, it looks like it opens the Adobe Reader plugin in the browser window, but no file is displayed until I hit refresh.
Here is my code:
[CheckSubscriber]
public ActionResult file(string path)
{
string mappedPath = Server.MapPath(
EncryptDecrypt.Decrypt(path,
EncString));
return base.File(mappedPath, "application/pdf");
}
How would I get this to work consistently in IE9?
I'm just thinking out loud here but maybe I am using the wrong mime-type?
You should be explicitly setting
Content-Disposition: inline; filename="foo.pdf"
The content-disposition is a crucial response header when returning a response from the server. All browsers will correctly detect the file 100% of the time if this is specified along with the MIME type.
You can use Fiddler to ensure that the response headers are in order.
Edit
You cannot use the "ActionResult" return type for your action to do this.
You need to use "FilePathResult" or "FileStreamResult" both of which can be found in the System.Web.MVC namespace.
Alternatively you can create a Custom Action Return Type and use that for this action.
The article I have provided gives step by step along with code as to how to go about doing this.
I would use Fiddler to see the difference between the request/response that the browsers send/receive and see if you can spot it from there.
Here's how I return an Excel file (pdf should be the same):
public FileResult DownloadErrors(string filename)
{
var file = System.IO.File.ReadAllText(filename);
return File(new System.Text.UTF8Encoding().GetBytes(file), "application/ms-excel", "Errors.csv");
}
Be sure to use FileResult instead of ActionResult.

Setting ContentType = "image/tiff" and sending an image is not working in IE

I need to send an image (as a downloadable file) from an ASP web page. It is working correctly in every browser except for IE (all versions).
Here is the server side code:
bool export = Request.QueryString["Export"] != null;
if (export)
{
byte[] allBytes = File.ReadAllBytes(#"C:\MyImage.tif");
Response.ContentType = "image/tiff";
Response.AddHeader("content-disposition", "attachment; filename=\"MyImage.tif\"");
Response.OutputStream.Write(allBytes, 0, allBytes.Length);
Response.OutputStream.Flush();
Response.End();
return;
}
And here is the JavaScript:
$('#ExportFrame').attr('src', 'Default.aspx?Export=true'); // ExportFrame is an iframe
In IE, I keep getting an error saying "Internet Explorer cannot download Default.aspx from localhost". I thought it might be an issue with loading it in an iframe element, but redirecting to the URL is not working either. The really odd thing is that going to the URL (/Default.aspx?Export=true) does not work the first time, but works every time after that. Again, this works in every browser I've tried except IE.
Any ideas?
Update:
The aspx page has the following code to keep the page from getting cached:
// Never cache this page
Response.CacheControl = "no-cache";
Response.AddHeader("Pragma", "no-cache");
Response.Expires = -1;
Removing the first 2 lines and leaving only Response.Expires = -1 resolved the issue.
AFAIK, you have to fix the file type association on the client for this to work. Known issue - Windows Updates often breaks this association resulting in this type of error message.
http://www.eggheadcafe.com/software/aspnet/36147698/office-updates-break-tiff-file-associations.aspx
UPDATE
1.) Create a blank text document on your desktop. (File.txt)
2.) Change the file extension from .txt to .tiff.
3.) Right click on the .tiff file and select open. On the next box choose “select program from a list of installed programs.
4.) Click on the browse button and browse to “C:\Program Files\Common Files\Microsoft Shared\MODI\12.0”.
5.) Select “MSPVIEW.EXE” and click “Open”.
6.) Select “Microsoft Office Document Imaging” and click OK.
7.) You will get a message saying it is unable to open the document. That is because it is not an actual graphic image. We are just setting the file association at this point.
8.) Repeat steps 1 – 7 and use .tif as apposed to .tiff because there are two different file extensions for this type of document.
The aspx page had the following code to keep the page from getting cached:
// Never cache this page
Response.CacheControl = "no-cache";
Response.AddHeader("Pragma", "no-cache");
Response.Expires = -1;
Removing the first 2 lines and leaving only Response.Expires = -1 resolved the issue. For some reason this was preventing the image from working properly in IE.

openning files in another browser page/tab

i have an action that return a file content. i added:
Response.AddHeader("Content-Disposition", "attactment; filename:\"" + survey.File + "\"");
so that the image would be opened in another tab/page, gets opened in the current tab/page.
whats wrong with the header?
The content-disposition header instructs the user agent how it should present the data, and it is usually used when serving up binary data (as opposed to plain text). When set to "attachment", the display of the content is contingent upon further action of the user. In other words, the user should receive a prompt and must decide what to do with the content (usually given an "Open" or "Save" option).
You can not programmatically force a hyperlink to open up in a new tab. Even if you could, you should not. This behavior should be controlled by the user agent. As a user, when I want to open something in a new tab, I use the mouse-wheel-click because that is how my browser is configured.
You cannot control browser's tab behaviour by using HTTP headers - there is nothing in your code that affects this.
What might help you is changing HTML code that points to your download - if you are using tag you can set its target attribute to _tab or _blank and it will work in many browsers.

Make PDF display inline instead of separate Acrobat Reader window

I've got an ASP.NET ashx class that retrieves data from a database, creates a PDF file using iTextSharp, and streams the PDF to the browser. The browser (IE and Firefox at least) is launching Acrobat Reader as a separate window to open the file. I'd like for it to display inline within the browser.
Is that something I can completely control from the server side? I'm already setting the Content-Type header to application/pdf, and I've tried setting Content-Disposition and Content-Length. Nothing so far has worked.
Is there another header I'm missing? Is there something in the PDF itself that tells the browser how to display it? Any other ideas?
Setting the content-disposition and content-type headers should do it, but you might also need to call Response.ClearHeaders() to clear other headers that have been set.
Also, try using Fiddler to see the actual headers and content from the response and compare them to those from a site that works like you want.
If you are using an ashx (web handler) try this:-
context.Response.AddHeader("content-disposition", "inline; filename=Something.pdf")
OK, turns out it was a stupid question, but I'm glad I asked it because I had never heard of Fiddler (which led me to the answer, which is why I'm accepting tspauld's answer). The PDF is generated by a web service that serves the file to a couple of different front-end sites. I was setting the content disposition to inline in the service, but that didn't matter, because the browser never got that header; it got the header from the front-end site (which was attachment). I changed it in the front-end site and that fixed it.
So the answer is that you have to have Content-Type=application/pdf and Content-Disposition=inline; filename=Something.pdf, as others have said.
Try generating them into your page using html OBJECT.
<OBJECT WIDTH=640 HEIGHT=480>
<PARAM NAME="SRC" VALUE="<%=filePath%>">
<EMBED SRC=<%=filename.pdf%> WIDTH=1000 HEIGHT=680>
<NOEMBED> PDF should have displayed here!</NOEMBED>
</EMBED>
</OBJECT>
If you need to stream the response with an ashx instead of being able to return an aspx, I think you may be out of luck.
Otherwise, I believe the settings to show in browser or not, is completely client driven and out of your hands.
So, I have a sample in one of my works that is what you need:
<cc1:ShowPdf ID="ShowPdf1" runat="server" BorderStyle="None" BorderWidth="0px"
Height="750px" Style="z-index: 103; "
Width="750px"/>
and in server side :
ShowPdf1.FilePath = String.Format("~/Handlers/Pdf.ashx?id={0}#view=FitH&page=1&pagemode=none&navpanes=1", myPublicationId);
I place here also some code from my PDF Handler :
Response.ContentType = "application/pdf";
byte[] bytes = YourBinaryContent;
using (BinaryWriter writer = new BinaryWriter(context.Response.OutputStream))
{
writer.Write(bytes, 0, bytes.Length);
}
Anyway If my post doesn't seem clear to you, have a look at this sample How to Display PDF documents with ASP.NET
I think this header will do what you want
Content-type: application/pdf
Since you say that is not working, then I suspect it is a configuration setting on the client side.
Check your installed version of Adobe Acrobat. There is a setting in preferences for "Internet" and a checkbox that says "Display PDF in Browser".
--
bmb
Here is an article on using the embed tag to do it:http://blogs.adobe.com/pdfdevjunkie/2007/08/using_the_html_embed_tag_to_di.html
If you have the budget, my company sells a set of products that includes an AJAX based image viewer that will let you view the PDF pages in line without Acrobat at all. In its simplest form, it is just a viewer, but you can layer in interactivity as you need.

Resources