Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Response.End() vs HttpContext.Current.ApplicationInstance.CompleteRequest() [duplicate]

Tags:

c#

The users of our application download an attachment at least once in two seconds during the day.

Previous Scenario:

We were using Response.End() to abort the connection to the client after the user downloads an attachment. As we were having performance issues, we started logging exceptions and one of the most repeated one was the thread abort exception. Since we are getting the attachment from a web service, We have to do some clean up and we had the clean up in try-catch-finally block. After some research, I have understood that any code after Response.End() will not be executed even if it is in finally block. Is that right?

Current Scenario:

I've read the thread in stack overflow about Response.End() being harmful and it needs to be used only when it is really needed, so I decided to use HttpContext....CompleteRequest() instead. With this code, the clean up needed is done, but the html that is rendered is being appended to the attachment downloaded. I tried overriding the Render and RaisePostBackEvent suggested in the same article but the problem still persists. Any idea on how to resolve this issue would be helpful.

Code:

HttpContext.Current.Response.Clear();

Response.ClearContent();

Response.ClearHeaders();

Response.AddHeader("Content-Disposition", "attachment; filename=" +   
filename);
Response.AddHeader("Content-Length", fileContent.Length.ToString());
Response.ContentType = "application/octet-stream";
Response.BinaryWrite(fileContent);
Response.Flush();
like image 295
user1396468 Avatar asked May 15 '12 15:05

user1396468


2 Answers

Response.End internally throws the ThreadAbortException to kill the request - if you need to do some kind of cleanup, this needs to be done before the call to Response.End is made.

Response.Redirect and Response.End do not interact well with try / catch blocks. So in your situation, you should do all your logic writing to the response stream in your try / catch, then simply call Response.End after your finally block.

like image 105
Tejs Avatar answered Nov 14 '22 22:11

Tejs


Old Q, and not sure if it helps, but I do essentially the same as your example when creating PDF files to deliver to the browser. However, at the end of processing, I have the following:

    Response.OutputStream.Flush()
    Response.OutputStream.Close()
    Response.End()

The addition of .Close() basically. Seems to work fine in production.

Ed: Just found this too, mentioning Close(): Is Response.End() considered harmful?

Another approach to your problem is simply overriding Page_PreRender() and putting the content delivery code in there (which kind of makes functional sense). Then you definitely won't get any unwanted HTML, and there should be no need for Response.End() at all.

like image 40
ingredient_15939 Avatar answered Nov 14 '22 22:11

ingredient_15939