Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HttpResponse.End vs HttpResponse.Close vs HttpResponse.SuppressContent

Within an ASPX page, I want to end the response at specific points (not due to an error condition), depending on code path, so that nothing else is sent back down the stream. So naturally used:

Response.End(); 

This results in a ThreadAbortException, which is by design.

The following seems to work but does not look like the correct approach as per this SO question:

Response.Flush(); Response.Close(); 

So, how about this?

Response.Flush(); Response.SuppressContent = true 

and then just let the page complete normally.

I could just handle and swallow the ThreadAbortException, but I just want to find out if there is anything wrong/gotchas with the SuppressContent approach?

Edit: To give a bit more of an example. Say I have a ASPX page whereby I may change the content-type to one of a number of possibilities. Depending on the content-type and scenario, at a given point in the code I want to prevent any more content from being sent to the client. Assume after SuppressContent has been set set to true, that there is no issue with any further server-side code running. I just don't want anything else to be sent to the client.

Edit 2: MyPage.aspx - has a master page which may include standard content, headers, footers etc etc. This page can just render as a normal page. It also can just write out an (e.g.) XML document to be downloaded. If writing out an XML document (determined on page load), it will clear the ouput, set the content-type to XML, write all the XML out and then if left normally, you end up with the rest of the ASPX page rendering being tacked on to the end - that is obviously not required/breaks the XML.

Edit 3: For now I'm using the SuppressContent approach. To try and draw this question to a close, I'm raising a bounty and will put the question another way: When should you use SuppressContent? Why would you use it instead of Response.End?


Please see the answer I provided below for the solution I actually ended up with as I eventually found a way to avoid the ThreadAbortException when using Response.End. I had already excepted an answer by this point.


like image 281
AdaTheDev Avatar asked Dec 11 '09 08:12

AdaTheDev


People also ask

What do you use response end for?

The End method causes the Web server to stop processing the script and return the current result. The remaining contents of the file are not processed.

What is ASP Net Response end?

The Response. End method ends the page execution and shifts the execution to the Application_EndRequest event in the application's event pipeline. The line of code that follows Response. End is not executed.

Does response need end?

response. end() is always needed to let the server know we're done building the response send, anything left and close browser connection.


2 Answers

I know this is an old question, but I'm including this for the benefit of anyone who might stumble into this post. I've been chasing down a bug that led me to review my use of Response.End, and discovered an MSDN post from a year after this question that could be summarized as "Never, ever use Response.End". Here's what Thomas Marquardt, who designed the Integrated Pipeline for IIS7, says about it:

The End method is also on my “never use” list. The best way to stop the request is to call HttpApplication.CompleteRequest. The End method is only there because we tried to be compatible with classic ASP when 1.0 was released. Classic ASP has a Response.End method that terminates processing of the ASP script. To mimic this behavior, ASP.NET’s End method tries to raise a ThreadAbortException. If this is successful, the calling thread will be aborted (very expensive, not good for performance) and the pipeline will jump ahead to the EndRequest event. The ThreadAbortException, if successful, of course means that the thread unwinds before it can call any more code, so calling End means you won’t be calling any code after that. If the End method is not able to raise a ThreadAbortException, it will instead flush the response bytes to the client, but it does this synchronously which is really bad for performance, and when the user code after End is done executing, the pipeline jumps ahead to the EndRequest notification. Writing bytes to the client is a very expensive operation, especially if the client is halfway around the world and using a 56k modem, so it is best to send the bytes asynchronously, which is what we do when the request ends the normal way. Flushing synchronously is really bad. So to summarize, you shouldn’t use End, but using CompleteRequest is perfectly fine. The documentation for End should state that CompleteRequest is a better way to skip ahead to the EndRequest notification and complete the request.

From http://blogs.msdn.com/b/aspnetue/archive/2010/05/25/response-end-response-close-and-how-customer-feedback-helps-us-improve-msdn-documentation.aspx

like image 192
Eyeball Avatar answered Sep 23 '22 02:09

Eyeball


I eventually found a simple solution to using Response.End() without getting a ThreadAbortException.

Response.Flush(); Response.End(); 

From my original question, I'd always been trying JUST a Response.End() after sending some content to the response stream.

It seems that if there is unflushed content when you do Response.End(), you get the ThreadAbortException. By doing the Flush immediately before the End, a ThreadAbortException does not actually get thrown.

Seems to be working great - no ThreadAbortException is being thrown now when I use Response.End

like image 28
AdaTheDev Avatar answered Sep 22 '22 02:09

AdaTheDev