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.
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).
basically below is the code for me to read pdf file, the output for this code below is ask client to download the pdf file and open it from client side, this is not what i want,what i want it open the pdf at another browswer windows or open in inside tag under same browser windows, but how can i make it?
var fi = new FileInfo(Server.MapPath(#"~/AIA2.pdf"));
Response.Clear();
Response.AddHeader("Content-Disposition",
String.Format("attachment; filename=\"{0}\"",
"AIA2.pdf"));
Response.AddHeader("Content-Length", fi.Length.ToString());
Response.ContentType = "application/octet-stream";
Response.WriteFile(fi.FullName);
Response.End();
This is not upto the server to decide how content is handled - content disposition could be set to attachment or inline but its to the handling application to process these and i do not think any browser does that.
I can suggest a two step solution for this:
Use inline; instead of attachment
On the client side (if you have control on that ofcourse), use something like
That should do the trick!
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()