I try to load a small pdf file to client browser. I redirect to download_page.aspx that does the following:
Response.ClearHeaders();
Response.ContentType = "application/pdf";
Response.Clear();
Response.AppendHeader("Content-Disposition", "attachment");
Response.TransmitFile(file);
Response.Flush();
Problem:
When I redirect to download_page.aspx from a link or from a button.OnClientClick="javascript:window.open('download_page.aspx?index=20')"
it works. PDF opens in client browser.
However, when I click on a button that does something on the page and then i use ClientScript.RegisterStartupScript to redirect to download_page.aspx, then download_page.aspx just blinks (flashes) and closes, no pdf loaded.
This is IE7, IE8 problem. It works in Firefox.
Any help appreciated.
Thank you,
Raman.
First of all, you don't need to ClearHeaders Clear and Flush, so your code should look like:
Response.ContentType = "application/pdf";
Response.AppendHeader("Content-Disposition", "attachment");
Response.TransmitFile(file);
Now, you should also improve the Content-Disposition header value and add the file name to ease end-users browser experience. IE is different than other with regards with how the file name can be encoded in case it has special characters, so here is a sample code that you might use or change to your will:
public static void AddContentDispositionHeader(HttpResponse response, string disposition, string fileName)
{
if (response == null)
throw new ArgumentNullException("response");
StringBuilder sb = new StringBuilder(disposition + "; filename=\"");
string text;
if ((HttpContext.Current != null) && (string.Compare(HttpContext.Current.Request.Browser.Browser, "IE", StringComparison.OrdinalIgnoreCase) == 0))
{
text = HttpUtility.UrlPathEncode(fileName);
}
else
{
text = fileName;
}
sb.Append(text);
sb.Append("\"");
response.AddHeader("Content-Disposition", sb.ToString());
}
Now, your code can be written as:
Response.ContentType = "application/pdf";
AddContentDispositionHeader(Response, "attachment", filename);
Response.TransmitFile(file);
The last thing is: make sure nobody deletes the files or writes to it during its transmission.
I met the same condition as yours.
I finally solved it.
Don't use window.open. You can simply use
window.location = 'download_page.aspx?index=20'
Note that the original page will remain well.
Reference from here and from here
Related
I want to make the browser download a PDF document from server instead of opening the file in browser itself. I am using C#.
Below is my sample code which I used. It not working..
string filename = "Sample server url";
response.redirect(filename);
You should look at the "Content-Disposition" header; for example setting "Content-Disposition" to "attachment; filename=foo.pdf" will prompt the user (typically) with a "Save as: foo.pdf" dialog, rather than opening it. This, however, needs to come from the request that is doing the download, so you can't do this during a redirect. However, ASP.NET offers Response.TransmitFile for this purpose. For example (assuming you aren't using MVC, which has other preferred options):
Response.Clear();
Response.ContentType = "application/pdf";
Response.AppendHeader("Content-Disposition", "attachment; filename=foo.pdf");
Response.TransmitFile(filePath);
Response.End();
If you want to render the file(s) so that you could save them at your end instead of opening in the browser, you may try the following code snippet:
//create new MemoryStream object and add PDF file’s content to outStream.
MemoryStream outStream = new MemoryStream();
//specify the duration of time before a page cached on a browser expires
Response.Expires = 0;
//specify the property to buffer the output page
Response.Buffer = true;
//erase any buffered HTML output
Response.ClearContent();
//add a new HTML header and value to the Response sent to the client
Response.AddHeader(“content-disposition”, “inline; filename=” + “output.pdf”);
//specify the HTTP content type for Response as Pdf
Response.ContentType = “application/pdf”;
//write specified information of current HTTP output to Byte array
Response.BinaryWrite(outStream.ToArray());
//close the output stream
outStream.Close();
//end the processing of the current page to ensure that no other HTML content is sent
Response.End();
However, if you want to download the file using a client application then you'll have to use the WebClient class.
I use this by setting inline parameter to true it will show in browser false it will show save as dialog in browser.
public void ExportReport(XtraReport report, string fileName, string fileType, bool inline)
{
MemoryStream stream = new MemoryStream();
Response.Clear();
if (fileType == "xls")
report.ExportToXls(stream);
if (fileType == "pdf")
report.ExportToPdf(stream);
if (fileType == "rtf")
report.ExportToRtf(stream);
if (fileType == "csv")
report.ExportToCsv(stream);
Response.ContentType = "application/" + fileType;
Response.AddHeader("Accept-Header", stream.Length.ToString());
Response.AddHeader("Content-Disposition", String.Format("{0}; filename={1}.{2}", (inline ? "Inline" : "Attachment"), fileName, fileType));
Response.AddHeader("Content-Length", stream.Length.ToString());
//Response.ContentEncoding = System.Text.Encoding.Default;
Response.BinaryWrite(stream.ToArray());
Response.End();
}
In case if we are trying to write a bytes array then we can use below one.
Response.Clear();
Response.ContentType = "application/pdf";
Response.AppendHeader("Content-Disposition", "attachment; filename=file.pdf");
Response.BufferOutput = true;
Response.AddHeader("Content-Length", docBytes.Length.ToString());
Response.BinaryWrite(docBytes);
Response.End();
They are almost same in most of the cases but there is a difference:
Add Header will replace the previous entry with the same key
Append header will not replace the key, rather will add another one.
I want to send all currently buffer output (which is Some Random Codes to excel sheet) to client and navigate to other page.
I am facing problems like
If I use Response.End() the page stops executing and Response.Redirect doesn't execute.
If I use Response.Flush() the page sends the buffer output but at time of redirection I am getting exception "Cannot redirect after HTTP headers have been sent."
My code is like this:
// this code sends some codes to excel.
ExportToExcel(Codes);
Response.End(); // what should i use
Response.Redirect("Coupons.aspx");
The ExportToExcel mehtod:
public void ExportToExcel(List<string> codes)
{
Response.ClearContent();
Response.Buffer = true;
Response.AddHeader("content-disposition",
string.Format("attachment; filename={0}_CODES.xls", DateTime.Today.Date.ToString("d")));
// Response.AddHeader("content-disposition", #"attachment;filename=""MyFile.pdf""");
Response.ContentType = "application/excel";
List<string> codeList = codes;
string str = "COUPON CODES";
Response.Write(str);
str = "\t";
Response.Write("\n");
Response.Write("\n");
foreach (string code in codeList)
{
Response.Write(code);
Response.Write("\n");
}
}
This is my 1st time asking question here.. Any reply and suggestions will be helpful for me.
Thanks in advance.
I have a "Download PDF" button that render a ReportViewer and open it in browser using Adobe Reader.
Here's the code:
Warning[] warn = null;
String[] streamids = null;
String mimeType = "application/pdf";
String encoding = String.Empty;
String extension = String.Empty;
Byte[] byteViewer;
byteViewer = report.LocalReport.Render("pdf", null, out mimeType, out encoding, out extension, out streamids, out warn);
Response.Buffer = true;
Response.Clear();
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "inline; filename=" + fileName + ".pdf");
Response.BinaryWrite(byteViewer);
Response.Flush();
Response.End();
But now, instead of opening the pdf, i want to open a download dialog to download the file. What changes in the code should I do?
#edit
The answers in that question are way too extensive, my question was asked to simplify the process of downloading a ReportViewer, and also adding a reference for future C# programmers that may encounter this question, without having to dig through lines of useless php code to find the answer.
To simplify the code for future StackOverflow users that may find this question:
in Response.AddHeader("content-disposition", "inline; filename=" + fileName + ".pdf");, just change inline to attachment, and that will download the file instead of opening in the browser.
This answer is too simple, so I will check "community wiki" to be fair.
I have designed a website through which when i click a button a .EXE file should download from specific path from my computer.
But its not downloading the exe file instead its downloading the aspx page of the website.
I use the following code:
WebClient myWebClient = new WebClient();
// Concatenate the domain with the Web resource filename.
myWebClient.DownloadFile("http://localhost:1181/Compile/compilers/sample2.exe", "sample2.exe");
Can you please try this.
string filename = "yourfilename";
if (filename != "")
{
string path = Server.MapPath(filename);
System.IO.FileInfo file = new System.IO.FileInfo(path);
if (file.Exists)
{
Response.Clear();
//Content-Disposition will tell the browser how to treat the file.(e.g. in case of jpg file, Either to display the file in browser or download it)
//Here the attachement is important. which is telling the browser to output as an attachment and the name that is to be displayed on the download dialog
Response.AddHeader("Content-Disposition", "attachment; filename=" + file.Name);
//Telling length of the content..
Response.AddHeader("Content-Length", file.Length.ToString());
//Type of the file, whether it is exe, pdf, jpeg etc etc
Response.ContentType = "application/octet-stream";
//Writing the content of the file in response to send back to client..
Response.WriteFile(file.FullName);
Response.End();
}
else
{
Response.Write("This file does not exist.");
}
}
I hope my edited comment will help to understand. But note: It is just a rough summary. You can do a lot more than this.
I am trying to programatically download a file through clicking a link, on my site (it's a .doc file sitting on my web server). This is my code:
string File = Server.MapPath(#"filename.doc");
string FileName = "filename.doc";
if (System.IO.File.Exists(FileName))
{
FileInfo fileInfo = new FileInfo(File);
long Length = fileInfo.Length;
Response.ContentType = "Application/msword";
Response.AddHeader("Content-Disposition", "attachment; filename=" + fileInfo.Name);
Response.AddHeader("Content-Length", Length.ToString());
Response.WriteFile(fileInfo.FullName);
}
This is in a buttonclick event handler. Ok I could do something about the file path/file name code to make it neater, but when clicking the button, the page refreshes. On localhost, this code works fine and allows me to download the file ok. What am I doing wrong?
Thanks
Rather than having a button click event handler you could have a download.aspx page that you could link to instead.
This page could then have your code in the page load event. Also add Response.Clear(); before your Response.ContentType = "Application/msword"; line and also add Response.End(); after your Response.WriteFile(fileInfo.FullName); line.
Try a slightly modified version:
string File = Server.MapPath(#"filename.doc");
string FileName = "filename.doc";
if (System.IO.File.Exists(FileName))
{
FileInfo fileInfo = new FileInfo(File);
Response.Clear();
Response.ContentType = "Application/msword";
Response.AddHeader("Content-Disposition", "attachment; filename=" + fileInfo.Name);
Response.WriteFile(fileInfo.FullName);
Response.End();
}
Oh, you shouldn't do it in button click event handler. I suggest moving the whole thing to an HTTP Handler (.ashx) and use Response.Redirect or any other redirection method to take the user to that page. My answer to this question provides a sample.
If you still want to do it in the event handler. Make sure you do a Response.End call after writing out the file.