Capturing the Output of ASP.NET Pages

Published 01 June 04 04:19 PM | despos

If you want to add a signature (for whatever purpose) to all pages your ASP.NET app serves to the browser, you can write an application event handler to intercept the EndRequest event or, better yet, the PreSendRequestContent event. The latter, in fact, occurs just before the HTTP content is sent to the browser; the former is the last chance you have to send text to the browser during the request.

For a (too) long time, I made myself convinced that a PreSendRequestContent handler would have offered the opportunity to modify the outgoing markup. All application events like EndRequest and PreSendRequestContent provide access to the HTTP context and, from here, to the response object stream--the OutputStream property of the HttpResponse class.  

The problem is that the response's output stream is write-only, presumably for performance reasons. Any attempt to read the output stream fails. The actual class is an internal class named HttpResponseStream in which CanRead and CanSeek return false and length and position functions (required by Stream-based classes) just throw a NotSupported exception.

If you simply want to append text to the request's response, an application event (either in global.asax or in a HTTP module) is fine. If you want to process the content outside the page code, use a response filter object.

A response filter object is a custom Stream that you register with the Filter property of the HttpResponse object. This content of the output stream is passed through this stream before the PreSendRequestContent event occurs. In this way, you can modify the content of the page at will.  

This is the only way you (seem to) have in ASP.NET 1.x to capture the output of a Web page. To do what?

I've found trick of essential importance to enhance the trace output of a page. 

Comments

# Milan Negovan said on June 1, 2004 10:39 AM:

I agree---response filters are handy for modifying page outputs. I use response filters a lot to force compliancy with XHTML 1.0 and love them.

If you don't want to go through the hassle of writing a filter, wiring it, etc you can simply tap into the Page.Render method. We've had a dicussion along these lines at the <a href="http://asp.net/Forums/ShowPost.aspx?tabindex=1&PostID=478027">ASP.NET Forums</a>.

# Milan Negovan said on June 1, 2004 10:39 AM:

Oops, the link was supposed to be: http://asp.net/Forums/ShowPost.aspx?tabindex=1&PostID=478027

# Rick Strahl said on June 11, 2004 11:45 PM:

The filter is pretty limited though because you can't look at the page as a whole only the incoming bytes which may or may not be the entire document. Although in my tests it looks like the page is written in batch I suspect that there are situations where the thing won't write as a whole. Buffering may also play into that. This means that searching the content could be problematic unless you capture everything as it comes and then later assemble it and write it to the OutputStream yourself. Question is what do you use to store it in in between potential calls? Context?

It's also a bad idea to filter content at this level if you're going to add stuff to the content because now you'd have to check the output content type and make sure you only write it out HTML based content for example. You wouldn't want to write out stuff to WebService content of your app for example. For situations like that it might make more sense to override Page.Render() (or equivalent if you're doing it in a Web Service for example) and capture the output stream where you still have a chance to write to it and modify it as a whole.

# TrackBack said on September 28, 2004 11:52 AM:
# TrackBack said on September 28, 2004 11:55 AM:
# Alberto Casu said on October 17, 2007 05:37 PM:

Talvolta può rendersi necessario &quot;trattare&quot; l&#39;output di una applicazione asp.net che non

# Alberto Casu said on October 17, 2007 05:51 PM:

Talvolta può rendersi necessario &quot;trattare&quot; l&#39;output di una applicazione asp.net che non

Leave a Comment

(required) 
(required) 
(optional)
(required)