This code is in control.ascx and control is put in ModalPopup.aspx page.
First ai try with response.end() - this code throw exception.
After ai try coment this line, but nothing is hapen.
Browser is IE8
try
{
//export
StringBuilder sb = ExportToExcelXml();
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
byte[] byteText = encoding.GetBytes(sb.ToString());
Response.Clear();
Response.Charset = "utf-8";
Response.ContentType = "text/xls";
Response.AddHeader("content-disposition", "attachment; filename=export.xls");
Response.BinaryWrite(byteText);
//Response.End();
}
catch (Exception ex)
{
Once the response has been started, you cannot clear it and change it's content type. In the case of an .ascx file, you're inside an .aspx file which is probably already started filling out the response. Can you move this to a .ashx (Generic Handler) instead?
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.
My code is like this
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.ContentType = "application/pdf";
HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment; filename=" + "name" + ".pdf");
HttpContext.Current.Response.TransmitFile("~/media/pdf/name.pdf");
HttpContext.Current.Response.End();
if (FileExists("/media/pdf/name.pdf"))
{
System.IO.File.Delete("D:/Projects/09-05-2013/httpdocs/media/pdf/name.pdf");
}
Here I want to download name.pdf in the browser, and after the download I want o delete that file.But the code execution stops at
HttpContext.Current.Response.End();
no code after that line is executed.so my delete function is not working.Is there any work around for this issue?
// Add headers for a csv file or whatever
Response.ContentType = "text/csv"
Response.AddHeader("Content-Disposition", "attachment;filename=report.csv")
Response.AddHeader("Pragma", "no-cache")
Response.AddHeader("Cache-Control", "no-cache")
// Write the data as binary from a unicode string
Dim buffer As Byte()
buffer = System.Text.Encoding.Unicode.GetBytes(csv)
Response.BinaryWrite(buffer)
// Sends the response buffer
Response.Flush()
// Prevents any other content from being sent to the browser
Response.SuppressContent = True
// Directs the thread to finish, bypassing additional processing
HttpContext.Current.ApplicationInstance.CompleteRequest()
HttpResponse.End (as per documentation) raises a ThreadAbortException and as you do no attempt to handle this your method exits.
I'm not sure exactly why you must use End(), but you could put the "cleanup" code in a finally statement.
Maybe fire some async method (fire and forget style) to delete the file or have a clean-up service on the server to delete all your files after certain time and rule.
Like mentioned about Reponse.End is pretty harsh and final... more details here:
Is Response.End() considered harmful?
just my thoughts on that... =)
I had the same issue.
try this: copy to MemoryStream -> delete file -> download.
string absolutePath = "~/your path";
try {
//copy to MemoryStream
MemoryStream ms = new MemoryStream();
using (FileStream fs = File.OpenRead(Server.MapPath(absolutePath)))
{
fs.CopyTo(ms);
}
//Delete file
if(File.Exists(Server.MapPath(absolutePath)))
File.Delete(Server.MapPath(absolutePath))
//Download file
Response.Clear()
Response.ContentType = "image/jpg";
Response.AddHeader("Content-Disposition", "attachment;filename=\"" + absolutePath + "\"");
Response.BinaryWrite(ms.ToArray())
}
catch {}
Response.End();
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
Currently I have the text file going to desktop, in ASP how can I prompt a file save dialog for the user? The result is string from the streamreader as "result" as follows:
StreamWriter FileWriter = new StreamWriter(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "file.txt"));
FileWriter.Write(result);
FileWriter.Close();
String FileName = filename;
String FilePath = filepath;
System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
response.ClearContent();
response.Clear();
response.ContentType = "text/plain";
response.AddHeader("Content-Disposition", "attachment; filename=" + FileName + ";");
response.TransmitFile(FilePath + FileName);
response.Flush();
response.End();
Response.AppendHeader("Content-Disposition", "attachment");
StreamWriter FileWriter = new StreamWriter(Response.OutputStream);
FileWriter.Write(result);
I didn't try the code, but maybe you need to omit the call to FileWriter.Close() since it will try to dispose the stream. If not, then you should be using using instead. If it's too problematic, write to the stream directly with its Write method or use a MemoryStream.
An example from one of my apps that does it.
protected void Page_Load(object sender, EventArgs e)
{
string tempFileName = Request["tempFileName"]; // the temp file to stream
string attachFileName = Request["attachFileName"]; // the default name for the attached file
System.IO.FileInfo file = new System.IO.FileInfo(Path.GetTempPath() + tempFileName);
if (!file.Exists)
{
pFileNotFound.Visible = true;
lblFileName.Text = tempFileName;
}
else
{
// clear the current output content from the buffer
Response.Clear();
// add the header that specifies the default filename for the
// Download/SaveAs dialog
Response.AddHeader("Content-Disposition", "attachment; filename=" + attachFileName);
// add the header that specifies the file size, so that the browser
// can show the download progress
Response.AddHeader("Content-Length", file.Length.ToString());
// specify that the response is a stream that cannot be read by the
// client and must be downloaded
Response.ContentType = "application/octet-stream";
// send the file stream to the client
Response.WriteFile(file.FullName);
}
}
string path = Server.MapPath(your application path);
WebClient client = new WebClient();
byte[] data = client.DownloadData(new Uri(path));
Response.Clear();
Response.ContentType = "application/pdf";
Response.AppendHeader("Content-Disposition", String.Format("attachment; filename={0}", "aspnet.pdf"));
Response.OutputStream.Write(data, 0, data.Length);
try this code.. its helpful
Don't know if its still open but just to help others
Just use this code it should work to prompt the user to open a dialog for opening or saving the file on the system ....
byte[] bytesPDF = System.IO.File.ReadAllBytes(#"C:\sample.pdf");
if (bytesPDF != null)
{
Response.AddHeader("content-disposition", "attachment;filename= DownloadSample.pdf");
Response.ContentType = "application/octectstream";
Response.BinaryWrite(bytesPDF);
Response.End();
}
If I understand you correctly, you first had a 1-tier (desktop) app that was saving a file using C# to the user's file system. You are now trying to transition to a 2-tier app with your C# code running on the server tier, and the user's browser representing the other tier. There is nothing you can do in C# on the server to write a file to the browser user's file system directly.
That being said, what you need to do is write the file to the HTTP response stream with a content type of something like application/octet-stream. Are you actually using ASP or ASP.NET? If the latter, you should have access to the response stream through a variety of means, but start with the Response object (available from the page, but also available via HttpContext.Current.Response).