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.