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() behavior change in ASP.NET 2.0


:P
On this page:

 Here’s a cool new behavior in ASP.NET 2.0: Response.End() no longer kills post Application Handler events! In 1.1 if you called Response.End() ASP.NET inside of an HTTP Handler, the call caused the pipeline to effectively bypass the rest of the HttpApplication events. This could cause problems for any content modifying modules or Application level event hooks. In 2.0 post Handler events continue to fire.

 

The behavior seems to apply only to Response.End() operations that fire from within a handler – if you call Response.End() from within a module event (like Application.Authenticate) the request still ends.

 

I think this is the way it should work, but some people may find this change will break their existing applications if they relied on Response.End() to not do any further processing.

 

For my Core ASP.NET session I’m doing in Germany next week, I have one slide that talks about the problems with Response.End() in modules but it looks like this is no longer necessary. One of the examples I gave is adding a shareware message to the end of a request via a PostRequestHandlerExecute() method:

 

/// <summary>

/// Summary description for SharewareModule.

/// </summary>

public class SharewareMessageModule : IHttpModule

{

      private const string SharewareMessage =

            @"<br clear='all'><p><table align='center' width='100%' cellpadding='6' bgcolor='darkblue'>

<tr><td><img src='images/poweredbywwstore.gif'></td>

<td style='color:white;font-weight:bold' valign='center'>This is a <b>non-registered version</b> of the

<a href='http://www.west-wind.com/WestwindWebStore/' style='font-weight:bold;color:yellow;text-decoration:none'>West Wind West Wind Web Store</a>.

If you are running in a production environment, please <a href='http://www.west-wind.com/WestwindWebStore/' style='font-weight:bold;color:yellow;text-decoration:none'>register</a> this copy.

</td></tr></table>";

 

 

      #region IHttpModule Members

 

 

      public void Init(HttpApplication application)

      {

            application.PostRequestHandlerExecute += new EventHandler(application_PostRequestHandlerExecute);

      }

 

      public void Dispose()

      {

      }

 

      #endregion

 

 

      private void application_PostRequestHandlerExecute(object sender, EventArgs e)

      {

            HttpApplication app = (HttpApplication) sender;

           

            // *** Must make sure we don't add this to data responses!!!

            if (app.Context.Response.ContentType.ToLower() == "text/html")

                  app.Context.Response.Write(SharewareMessage);

 

      }

 

}

 

This works in 1.1 as long as Response.End() isn’t called anywhere at which point the message no longer gets appended. In 2.0 the PostRequestHandlerExecute event fires even when Response.End() is called so the message gets ALWAYS appended.


Besides the obvious issue of by passing the behavior which may be critical for content or security, it’s also quite common in my applications to use Response.End() for generic pages that manage their own output generation through other pages (via Server.Execute() or internal generation). These pages are supposed to cut short any further output.

 

 One example, is the generic MessageDisplay class I use to display status and or error messages in the system with a single line of code. These page calls get embedded into a page and need to tell the parent page to stop rendering. But I sure would hope that the modules still fire. Well, now they do…

 

BTW, the code above to append the shareware message on the bottom is probably not the best way to do this as it generates invalid HTML <g>. In fact, the way I actually do this is by intercepting the Page’s Render() method, but this is a lot less generic than an HTTP Module, since the Page class obviously has to inherit from the proper class in order for the behavior to be there. Modules or Application event hookups are much more generic and much harder to unhook if necessary. Another option would be a Response.Filter, but they tend to be a bit more work to set up and also slower to execute and manage as you have to look at every byte coming off the Response Stream... So since browsers seem to be OK with rendering HTML after the offical </html> tag I guess I can live with this for demo purposes. 

Now playing: Fu Manchu - Hell on Wheels

 


The Voices of Reason


 

Paul
June 15, 2006

# re: Response.End() behavior change in ASP.NET 2.0

Just curious,

I always follow Response.End() with a return; statement. Outside of throw, I find it hard to do anything else but that w/ any statements that are supposed to terminate processing, etc.

# DotNetSlackers: Response.End() behavior change in ASP.NET 2.0


Web Forms
January 15, 2007

# ASP.NET Forums - Purpose of the Response.End(); method ?


anonymous
January 20, 2007

# Response.Write is so NON asp.net!

Using Response.Write is imho very old-style. Why not simply add an asp:Label with the text and set it's Visible property to show/hide it?

Rick Strahl
January 20, 2007

# re: Response.End() behavior change in ASP.NET 2.0

Maybe you didn't read the post <s>. It's a module for one and it fires an event late in the pipeline. There's no page cycle left in PostRequestHandlerExecute and a module doesn't have access to the page (well it does, but not in this case).

Folks - being trendy is not helping you!

And aside from that remember this: Response.Write() is considerably more efficient than propping a label into the page cycle with Controls.Add. There's a place for that no and most of the time it's appropriate, but just because it's so 'NON asp.net' is a lousy reason to avoid it in the right place.

ASP.NET Forums
June 06, 2007

# Purpose of the Response.End(); method ? - ASP.NET Forums


Seth
January 14, 2009

# re: Response.End() behavior change in ASP.NET 2.0

Rick, thanks for this article, but I do not observe the same behavior. I have an HTTPModule that does some work in post- and pre- requestHandlerExecute handlers but after a call to Response.end, the next event to fire is the EndRequest handler.

Your article suggests that the PostRequestHandlerExecute handler should execute, but after extensive research I have not been able to make that work. Do you still see the behavior outlined in this article?

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