I am trying to open a PDF document to display within IE6. I am using the following snippet:
response.ContentType = healthMedia.MediaKey.MimeType;
response.ClearHeaders();
response.AddHeader("Content-Disposition", "inline; filename=" + mediaKeyId);
int contentLength = healthMedia.Content.Length;
response.AppendHeader("content-length", Convert.ToString(contentLength));
response.OutputStream.Write(healthMedia.Content, 0, contentLength);
healthMedia.MediaKey.MimeType; is equal to 'application/pdf'
This brings up the Save dialog. If I comment out Response.ClearHeaders(); I get a new window to popup but it's contents is a bunch of jibberish (random encoding text).
How can I get IE6 to open the PDF correctly?
-Nick
Have you tried Response.End() and also Response.Buffer = true? You may also need to set a caching policy.
In case it helps, here's a method I've used before to render in-browser PDFs...
Use response.BinaryWrite() instead of response.OutputStream.Write()
Related
I tried to get a pdf file opened in chrome but it seems to be stuck in the middle of somewhere during displaying process. The code seems to work because it can get PDF opened in IE, not sure why it got stuck in chrome. The screen will just grey out, show the "LOADING" sign, and stop at 7/8. The file is around 6MB or more.
public static void ReturnPDF(byte[] contents)
{
var response = HttpContext.Current.Response;
response.Clear();
response.AppendHeader("Content-Disposition", "inline;filename=" + "abc.pdf");
response.BufferOutput = true;
response.ContentType = System.Net.Mime.MediaTypeNames.Application.Pdf;
response.BinaryWrite(contents);
response.Flush();
response.Close();
response.End();
}
Any thoughts? Thanks
[UPDATE]
I tried firefox with version 30.0 and it WORKS. My IE is 8.0.7601.17514, which can also open pdf. My Chrome is 39.0.2171.95. Not sure wheather the version of the browser matters or not, here only chrome fails to open the inline PDF...
[SOLVED]
After adding content-length, chrome can open the inline PDF.
public static void ReturnPDF(byte[] contents)
{
var response = HttpContext.Current.Response;
response.Clear();
response.AppendHeader("Content-Disposition", "inline;filename=" + "abc.pdf");
//After adding Content-Length, chrome is able to open PDF inline
response.AppendHeader("Content-Length", contents.Length.ToString());
response.BufferOutput = true;
response.ContentType = System.Net.Mime.MediaTypeNames.Application.Pdf;
response.BinaryWrite(contents);
response.Flush();
response.Close();
response.End();
}
The OP's original code created the response like this:
response.Clear();
response.AppendHeader("Content-Disposition", "inline;filename=" + "abc.pdf");
response.BufferOutput = true;
response.ContentType = System.Net.Mime.MediaTypeNames.Application.Pdf;
response.BinaryWrite(contents);
response.End();
This code especially does not set the Content-Length header. Some web browser versions (not only Chrome but also certain versions of other browsers) without that header tend to prematurely consider the download finished.
Detecting when a download is finished on a connection initially created as persistent, may not be trivial if neither a non-identity Transfer-Encoding nor a Content-Length has been supplied.
Thus, the solution here is to add
response.AppendHeader("Content-Length", contents.Length.ToString());
before writing the contents.
Try with "Content-disposition: attachment" header.
Thanks mkl's suggestions.
I added the content length in the header and the pdf can be successfully opened in Chrome!
I am using a handler to get and display a PDF in the browser window using the code below:
byte[] byt = RetrieveDocument(int.Parse(context.Request.Params["id"]), context.Request.Params["title"]);
string file = WriteDocumentFilePDF(byt);
HttpContext.Current.Response.ContentType = "application/pdf";
HttpContext.Current.Response.AddHeader("content-length", byt.Length.ToString());
HttpContext.Current.Response.AddHeader("Content-Disposition", "inline; filename=programdetails.pdf");
HttpContext.Current.Response.BinaryWrite(byt);
HttpContext.Current.Response.End();
The function WriteDocumentFilePDF successfully writes the PDF to the temp directory. I have the above code working correctly in a different application. Am I missing something?
When debugging issues like this, I find that Fiddler is an invaluable tool; many many times it has saved me from simple mistakes. Also, this site http://www.c-sharpcorner.com/uploadfile/prathore/what-is-an-ashx-file-handler-or-web-handler/ gives an example of doing the same thing but with a GIF image. The difference between your example and his seems to be the use of Response.WriteFile() rather than the direct write to the Response using BinaryWrite().
I would perform a Response.ClearHeaders() before I set the content-type and I would remove the call to Response.End().
Does it make a difference if you pass the byte[] to memorystream first? So something like
byte[] byt = RetrieveDocument(int.Parse(context.Request.Params["id"]), context.Request.Params["title"]);
string file = WriteDocumentFilePDF(byt);
MemoryStream ms = new MemoryStream(byt);
And then add your headers
HttpContext.Current.Response.ContentType = "application/pdf";
HttpContext.Current.Response.AddHeader("Content-Disposition", "inline; filename=programdetails.pdf");
HttpContext.Current.Response.BinaryWrite(ms.ToArray());
HttpContext.Current.Response.End();
I have a byte array in the database and i need to show that in a pdf file format. Here is the way i did that. However, this doesn't work on Android tablets(checked in 2.3.5 and 3.2).
Response.Clear();
Response.ContentType = "application/octet-stream";
Response.BufferOutput = true;
Response.Buffer = false;
Response.AddHeader("Content-Length", binaryData.Length.ToString());
Response.AppendHeader("Content-Disposition", "inline;filename=ClientDocument.PDF");
// Response.BinaryWrite(binaryData);
Response.OutputStream.Write(binaryData, 0, binaryData.Length);
Response.End();
Can you guys think of any way i could make it work on all the browsers?
Appreciate the help
Thanks
Couple of things...
Change the content type to correct mime-type of PDF files. There are vast array of these in use application/pdf, application/x-pdf, application/acrobat, applications/vnd.pdf, text/pdf, text/x-pdf", we just use application/pdf.
Response.ContentType = "application/pdf";
Then if you want the browser to open and display the PDF file, remove the Content-Disposition header.
... or ... if you want the browser to download the PDF file change the Content-Disposition type to "attachment" rather than "inline".
Response.AppendHeader("Content-Disposition", "attachment;filename=ClientDocument.PDF");
Have you upgraded to latest version of Android on the test tablets/phones?
That fixed it for me when I had a similar problem (PDFs not opening or downloading when sent to browser from stream or byte[] on Android only).
I'm trying to send an xlsx file by using
Response.Clear();
Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName);
Response.AddHeader("Content-Length", file.Length.ToString());
Response.ContentType = "application/vnd-ms.excel";
Response.TransmitFile(file.FullName);
Response.End();
The IE dialog pops up and I can successfully save the file, then open it from the folder, that works fine and dandy. But if I click on "Open" in the IE dialog, I get a "myFile.xlsx couldn't be downloaded." I click on "Retry" and it opens Excel but pops up the "Excel cannot open the file 'myFile.xlsx' because the file format or file extension is not valid..." error.
I'm currently running the site from VS2010 in debug mode.
Does anybody know why it would let me save, but not open directly?
Edit
Chrome just downloads it. FF tried opening it but gives the error The file you are trying to open, 'myFile.xlsx.xls', is in a different format than specified by the file extension... I can choose to open it anyways and it successfully opens, but in readonly mode.
So, something funky is going on here.
fileName = "myFile.xlsx"
Edit 2
This is in IE 9. I've also tried octet-stream and application/vnd.openxmlformats-officedocument.spreadsheetml.sheet as the ContentType.
It is because your ContentType is wrong. Use
Response.ContentType = "application/vnd.ms-excel";
Edit
if it didnt work, can you try
FileStream sourceFile = new FileStream(file.FullName, FileMode.Open);
float FileSize;
FileSize = sourceFile.Length;
byte[] getContent = new byte[(int)FileSize];
sourceFile.Read(getContent, 0, (int)sourceFile.Length);
sourceFile.Close();
Response.ClearContent();
Response.ClearHeaders();
Response.Buffer = true;
Response.ContentType = "application/vnd.ms-excel";
Response.AddHeader("Content-Length", getContent.Length.ToString());
Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName);
Response.BinaryWrite(getContent);
Response.Flush();
Response.End();
I had the same problem once, and solved by revising caching instructions sent by application server, in this case, IIS. Sometimes you add headers at application level that prevents the file from being saved in some conditions, like in HTTPS connections. Make sure that you aren't putting conflicting instructions.
I ran into similar issue.
Turned out I was reading from end of the stream so, the byte array wasn't getting filled with anything.
Setting the stream position to 0 (sourceFile.Position=0;) just before reading the stream (sourceFile.Read(getContent, 0, (int)sourceFile.Length);) fixed it for me.
See if that helps.
As for "Response.ContentType", "application/vnd.ms-excel" worked for me.
FileStream sourceFile = new FileStream(file.FullName, FileMode.Open);
float FileSize;
FileSize = sourceFile.Length;
byte[] getContent = new byte[(int)FileSize];
sourceFile.Position=0;
sourceFile.Read(getContent, 0, (int)sourceFile.Length);
sourceFile.Close();
Response.ClearContent();
Response.ClearHeaders();
Response.Buffer = true;
Response.ContentType = "application/vnd.ms-excel";
Response.AddHeader("Content-Length", getContent.Length.ToString());
Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName);
Response.BinaryWrite(getContent);
Response.Flush();
Response.End();
By coincidence I'm right in the middle of something similar...
The MIME type to use for xlsx is application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, see this question.
I was stumped by this issue, particularly with longer files.
Turned out in our case using the Content-Length header fixed the issue. Once the content gets over a certain length, you get this issue.
Example (where tempsbldr is a StringBuilder):
Response.AddHeader("Content-Length",tempsbldr.Length.ToString());
Im using ssrs through a reports server to generate a resultStream byte array using ReportExecutionService.Render() which I am currently serving to the user with the following code. Is there a way I can use this same byte array to automatically open the report in a new browser window instead of going to the save/open dialog?
public void RenderReport (byte[] reportDigits, ReportItem reportItem)
{
HttpResponse response = HttpContext.Current.Response;
response.Clear();
response.ContentType = reportItem.ReportMimeType;
response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}", reportItem.ExportName));
response.OutputStream.Write(reportDigits, 0, reportDigits.Length);
response.End();
}
In the past I have used a separate ReportViewer.aspx page that I would open first then display the report but would like to do it all in code behind if that is possible.
Thanks
It's this line:
response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}", reportItem.ExportName));
Thats causing it to be downloaded. Comment out that line, and as long as the browser can handle the mime type, it will render in the browser window.
Simply change the Header that you are adding to something other than an attachement. Make it the format of your data--and hopefully the browser will recognize it.