Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
Markdown Monster - The Markdown Editor for Windows

Response.End() bites back at HttpApplication events


:P
On this page:

Did you know that the ASP.Net pipeline can often get forestalled so that events on the HttpApplication object are not always fired? This is significant if you build HttpModules or Application event hooks or even if you hook logic to Render methods of a Page object.

 

I ran into this with an application that optionally can run in ‘shareware’ mode which embeds some content on the bottom of the form. This code is hooked via an HttpApplication event handler hooked onto PostRequestHandlerExecute.

 

Anytime your code calls Response.End() the remainder of the ASP.Net pipeline is not called. This means that HTTPModules that hook EndRequest, PostRequestHandlerExecute etc. will not fire. The same is true for things like ResponseFilters which also are left high and dry – anything that relies on code running after the page executes never gets executed.

 

Think this isn’t a problem? All it takes is somebody in an ASPX page doing:

 

<% Response.End(); %>

 

at the very bottom and the rest of the event chain is toast…

 

Response.End() affects other things as well. Consider that Server.Transfer() implicitly calls Response.End() which means that any transferred pages also don’t get the above shareware message. Server.Transfer() does not fire the ASP. Net pipeline (HttpApplication events), but simply transfers to another page and continues writing the output. When it’s done it doesn’t an implicit Response.End()/HttpApplication.CompleteRequest().

 

So, if you do something like this:

 

private void Page_Load(object sender, System.EventArgs e)

{

      Response.Write("<h1>Hello Cruel World</h1> ");

      Server.Transfer("default.aspx",false);

      Response.Write("<h1>Goodbye Cruel World</h1>");

}

 

you end up getting Hello Cruel World plus the output of default.aspx on the same page but not he Goodbye. The last Response.Write never fires though because Server.Transfer() issues an implicit Response.End(). You also don’t get the output from any HttpModules that might otherwise fire on every request. Server.Transfer, literally transfers control to the other page, but doesn’t re-run the entire HTTP pipeline event chain.

 

This is yet another reason why Server.Transfer() may be a problem in an application. If you need your HttpModules to fire it might just be a better approach to capture the output from Server.Execute() and write it out on your own, rather than issuing a Server.Transfer().

 

Server.Execute() works in that you can capture the output from another page and then embed it into the current page like this:

 

private void Page_Load(object sender, System.EventArgs e)

{

      Response.Write("<h1>Hello Cruel World</h1>");

     

      // *** Now call the other page and load into StringWriter

      string MergedText = null;

      StringWriter sw = new StringWriter();

      try

      {

            Context.Server.Execute("default.aspx",sw);

            MergedText =  sw.ToString();

      }

      catch

      {

            MergedText = null;

      }

      Response.Write(MergedText);

 

      Response.Write("<h1>Goodbye Cruel World</h1>");

}

 

This works as expected AND you get the HttpModule events to fire from the main page. Note that the Events fire only for the calling page, and not for the called page which is like the Transfer() simply executed inline of the current request, state and context.


Like Server.Transfer() the page the is Executed() does not fire the HttpApplication events either – it’s transferred to inline in the current request context, on the spot. This should not be a problem since with the above approach the events fire at least once, but it could be a problem if you’re trying to capture the page output for saving/emailing or whatever.


The Voices of Reason


 

Ron Liu
May 27, 2005

# re: Response.End() bites back at HttpApplication events

Rick, Thank you very much to point to this out. I am trying to implement file download function with asp.net C# and using Response.BinaryWrite(), then called Response.End(). Then the rest of code seems do not gets executed. It took me a day trying to figure out.
But almost every body on the world said "Response.End() has to be called" to clean up the buffer, otherwise....

What should I do?

Thanks

Rick Strahl
May 28, 2005

# re: Response.End() bites back at HttpApplication events

Response.End() is not required unless you need to end a request in the middle of processing. Response output is autoamtically closed when the request completes.

If you really need to exit out early there are usually there are other ways to get out of your code with proper structured statements, but you have to know that in order to not take the Response.End shortcut <g>...

sridhar
July 26, 2005

# re: Response.End() bites back at HttpApplication events

I am trying to send export excel sheet.
I have to use response.end or response.flush to display the excel sheet but I want to execute some other statements after the respnse.end so what I have to do .
I spent 2 days to solve this problem please help me
thanks
sridhar

Michalis Athens
October 03, 2005

# re: Response.End() bites back at HttpApplication events

Try calling the Handler on your own in the new
page init or load method

this.Prereder += new Handel(HTTPMODULE.OnPrereder)

I had the same problem and solve it with this
trick
(You can do a MasterPage that all pages inherite from with this line of code)

Thanks
Michalis

bubbabob
October 14, 2005

# re: Response.End() bites back at HttpApplication events

I also am trying to do an export to an excel sheet; when I execute the Response.End, I get an error to the effect that "the thread was being terminated". Any ideas?

Rick Strahl
October 14, 2005

# re: Response.End() bites back at HttpApplication events

Response.End causes an exception to occur and the .NET framework eats this error normally. but if you have a custom error handler that overrides the default ASP.NET error chain you will get that exception. You need to capture that error and override or skip over it when it occurs...


Hnaik
December 24, 2005

# re: Response.End() bites back at HttpApplication events

How will i handle the events of file download dialog window opened with open save cancel button and also how will i come to know which button user have clicked

Ajeet
February 10, 2006

# re: Response.End() bites back at HttpApplication events

Hi Rick,

I need to have an ErrorHandling HttpModule. This module will need to hook onto the PostRequestHandlerExecute event. However, if I do a context.adderror() in the Httphandler, then the module doesnt even get called. Like you said, it skips the whole chain. I cannot handle the error in the handler, because that is third party.

How do i solve this?

Regards,
Ajeet

Jig
December 02, 2009

# re: Response.End() bites back at HttpApplication events

Is it possible to execute:

Context.Server.Execute("default.aspx",sw);

in a thread so the user can carry on with it's work?

Thank you!

Jig

Rick Strahl
December 02, 2009

# re: Response.End() bites back at HttpApplication events

@Jig - haven't tried it, but I don't think so. Server.Execute transfers execution to another handler but stays on the same HttpContext instance and thread that was active before the transfer. I believe .NET 4.0 will get a TransferRequest method which effectively launches a completely new server side request but without the client side redirect.

West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2024