views:

172

answers:

1

I have some code that is used to replace certain page output with other text. The way I accomplish this is by setting the Response.Filter to a Stream, Flushing the Response, and then reading that Stream back into a string. From there I can manipulate the string and output the resulting code. You can see the basic code for this over at http://stackoverflow.com/questions/483091/render-a-view-as-a-string .

However, I noticed that Page Caching no longer works after the first Response.Flush call.

I put together a simple ASP.NET WebApp as an example. I have a Default.aspx with an @OutputCache set for 30 seconds. All this does is output DateTime.Now.ToLongTimeString(). I override Render. If I do a Response.Flush (even after the base.Render) the page does not get cached. This is regardless of any programmatic cacheability that I set.

So it seems that Response.Flush completely undermines any page caching in use. Why is this?

extra credit: is there a way to accomplish what I want (render output to a string) that will not result in Page Cache getting bypassed?

ASPX Page:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="TestCacheVsFlush._Default" %>
<%@ OutputCache Duration="30" VaryByParam="none" %>
<%= DateTime.Now.ToLongTimeString() %>

Code-behind (Page is Cached):

    protected override void Render(HtmlTextWriter writer)
    {
        base.Render(writer);
    }

Code-behind (Page is not cached):

protected override void Render(HtmlTextWriter writer)
{
    base.Render(writer);
    Response.Flush();
}

Code-behind (Page still is not cached):

protected override void Render(HtmlTextWriter writer)
{
    base.Render(writer);
    Response.Cache.SetCacheability(HttpCacheability.Server);
    Response.Cache.SetExpires(DateTime.Now.AddSeconds(30));
    Response.Flush();
}
+2  A: 

Okay, I think I have a partial answer for you.

From here:

Output cache module populates the IHttpCachePolicy intrinsic in BeginRequest stage if a matching profile is found. Other modules can still change cache policy for the current request which might change user-mode or kernel mode caching behavior. Output cache caches 200 responses to GET requests only. If some module already flushed the response by the time request reaches UpdateRequestCache stage or if headers are suppressed, response is not cached in output cache module.

That article is IIS7 specific, so not sure how this translates across to other versions, but it's probably similar. UpdateRequestCache is one of the HttpApplication pipeline events, and it occurs after an IHttpHandler (e.g. your Page object) has finished handling the request.

So... it doesn't look good for performing a flush inside your Page.

womp
FYI, this is happening in IIS6 too.
statichippo