Response.End() bites back at HttpApplication events
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.
Other Posts you might also like
The Voices of Reason
# re: Response.End() bites back at HttpApplication events
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>...
# re: Response.End() bites back at HttpApplication events
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
# re: Response.End() bites back at HttpApplication events
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
# re: Response.End() bites back at HttpApplication events
# re: Response.End() bites back at HttpApplication events
# re: Response.End() bites back at HttpApplication events
# re: Response.End() bites back at HttpApplication events
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
# re: Response.End() bites back at HttpApplication events
Context.Server.Execute("default.aspx",sw);
in a thread so the user can carry on with it's work?
Thank you!
Jig
# re: Response.End() bites back at HttpApplication events
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