Exception generated by Response.End() - c#

I am letting user download file using following code. It works fine but also generates error and source for error is Response.End();
Error Message :Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack.`
Below is my code. How can i handle this error and is this error not freeing my resources which can result in unwanted memory use.
I use this for asp.net webform application.
try
{
string fileName = Request["file_ID"];
string path = Server.MapPath("~/App_Data/uploads/"+fileName);
//string = Server.MapPath(strRequest);
System.IO.FileInfo file = new System.IO.FileInfo(path);
if (file.Exists)
{
Response.Clear();
Response.AddHeader("Content-Disposition", "attachment; filename=" + file.Name);
Response.AddHeader("Content-Length", file.Length.ToString());
Response.ContentType = "application/"+file.Extension;
Response.WriteFile(file.FullName);
Response.End();
// System.Threading.Thread.Sleep(2000);
// Page.ClientScript.RegisterStartupScript(this.GetType(), "MyScript", "alert('aa')", true);
}
else
{
//Page.ClientScript.RegisterStartupScript(this.GetType(), "MyScript", "myWindow.close();", true);
}
}
catch (Exception rt)
{
Response.Write(rt.Message);
}
}
I was looking at this solution but i am not sure how i can implement it in my code.
Unable to evaluate expression... on web page
UPDATE:
I actually want user to download file and close same with using code behind script which are commented in code right now.
So i am not sure how to better optimize this code to handle the exception generated by respond.end statement.
I tried to use Page.ClientScript.RegisterStartupScript(this.GetType(), "MyScript", "myWindow.close();", true); but it doesn't work either.
Thanks

The other answer seems to be saying you can either not use Response.End as it is unnecessary, or add a catch for ThreadAbortException where you have your current catch
The question links to another question that suggests adding the following:
// Sends the response buffer
Response.Flush()
// Prevents any other content from being sent to the browser
Response.SuppressContent = TrueResponse.SuppressContent = True

use HttpContext.Current.ApplicationInstance.CompleteRequest
OR TRY SOMETHING LIKE
Response.OutputStream.Flush()
Response.OutputStream.Close()
Response.Flush()
Response.End()
READ Is Response.End() considered harmful?

Related

What are the reasons for not deleting the pdf file in server? But in local it works

Here is some part of my code..
if (fileInfo.Exists) {
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.Buffer = true;
HttpContext.Current.Response.ContentType = contentType;
HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + hdnFileName.Value + "." + extension);
try {
HttpContext.Current.Response.WriteFile(hdnReportPath.Value);
Response.Flush();
HttpContext.Current.ApplicationInstance.CompleteRequest();
} catch (Exception ex) {
AppException appEx = AppException.Handle(ex, string.Format("Agency:{0} User:{1}", agencyID, userId));
} finally {
}
}
if (fileInfo.Exists)
File.Delete(hdnReportPath.Value);
It does not produce any exception or error, but it is not working in server(IIS), It works good in local. What are the reasons for not deleting the pdf file in server?
Thanks in advance....
check the permission of folder of your application which you host in IIS.
it might be effect while save/delete.
You check the file exists, if it does then you create it. Then check if it exists and delete it if it does...
There seems to be something wrong with your logic here. If the file doesn't exist nothing will ever happen.

Trouble cleaning up after serving generated file from asp.net Page_Load

I want to serve a dynamically created binary file from an asp.net web page via a http request parameter like so: www.host.com/?Download=file. So far I have
protected void Page_Load(object sender, EventArgs e)
{
if (Request.Params.Allkeys.Contains("Download"))
{
String fileStr = Request.Params.GetValues("Download")[0];
using (Stream generatedFile = File.Create(#"C:\Temp\file"))
{
/* write the contents of the file */
}
Response.ContentType = "application";
Response.AddHeader("Content-Disposition",
"attachment; filename=" + fileStr);
Response.WriteFile(#"C:\Temp\file");
Response.End();
}
}
which works, but C:\Temp\file still exists and I'd like it cleaned up. Calling File.Delete(#"C:\Temp\file"); after Response.End() doesn't work, since Response.End() kills the thread. Putting the Response methods inside the using block, with File.Create( (...), FileOptions.DeleteOnClose) doesn't work, since the Response methods then fail to get access to the file.
Any suggestions?
After writing file to response you can call Response.Flush to make sure it was fully written, and then delete it before calling Response.End:
Response.WriteFile(#"C:\Temp\file");
Response.Flush();
File.Delete(#"C:\Temp\file");
Response.End();

how to make code execute after Response.end

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();

Response.TransmitFile(filePath) fails in child page in IE

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

wait till code executes before running redirect

I have a page redirect that runs after a string is written to an MSword doc using WebClient and StringBuilder.
HttpContext.Current.Response.Write(strHTMLContent);
this.Page.Response.Redirect("http://www.google.com");
HttpContext.Current.Response.End();
However the string never gets written (or it doesn't get the chance to) since the redirect happens instantly.
How can i make my redirect run only until the string Write has occurred?
Thanks guys
This is the code used to generate the MSWord:
HttpContext.Current.Response.Charset = "";
HttpContext.Current.Response.ContentType = "application/msword";
string strFileName = "GenerateDocument" + ".doc";
HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename=" + strFileName);
StringBuilder strHTMLContent = new StringBuilder();
The redirect ends all processing and instructs the browser where to point to next. What you may want to do is write the data you wish your user to see, but include a meta refresh or similar mechanism as outlined in the Wikipedia article.
Correct me if I'm wrong, but if he were to put this in a try/catch/finally the refresh wouldn't execute until after the response was written right?
try
{
HttpContext.Current.Response.Write(strHTMLContent);
HttpContext.Current.Response.End();
}
catch(Exception ex)
{
//handle exception
}
finally
{
this.Page.Response.Redirect("http://www.google.com");
}

Categories