views:

925

answers:

3

Hi,

I'm trying to understand the ASP.NET OutputCache mechanism.
I built a test page with a Label and LinkButton.
The label text is being initialized on the server with the current server date on every PageLoad:

protected void Page_Load(object sender, EventArgs e)  
{  
    lblDate.Text = DateTime.Now.ToString();  
}

I used this directive: <%@ OutputCache Duration="600" VaryByParam="none"%>

When I press the LinkButton the first time I get a new text in the Label but if I press the linkbutton again I don't get a new text.

I assume this is because of the parameters that are being transfered to the server that are the same for each postback.

Is there any way to work with OutputCach and postback controls?

A: 

What you need is post-cache substitution:

Dynamically Updating Portions of a Cached Page

apathetic
A: 

You are correct in your assumptions.

Your OutputCache directive is telling the output caching mechanism to cache the entire rendered page for a specific URL, for 600 seconds.

In your simple example, you're probably not using any query strings, however, the VaryByParam declaration within the directive allows you to specify a query string parameter that ensures each different value of that parameter is cached separately. For example, if you had:

<%@ OutputCache Duration="600" VaryByParam="ProductID"%>

then these three different URL's would each be cached individually, and changing the value of the "ProductID" parameter to something not yet cached would ensure that the page is processed and rendered by the ASP.NET runtime correctly:

http://www.example.com/viewproduct.aspx?ProductID=123
http://www.example.com/viewproduct.aspx?ProductID=3
http://www.example.com/viewproduct.aspx?ProductID=67

In your example, on your button click, the page has already been previously rendered (and cached) and when you post back again there is no difference in the URL that you are posting back to and effectively reloading, therefore, the ASP.NET runtime will display the cached page to you without going through the process of re-rendering it.

Other than by changing the value of a "VaryByParam" parameter, the OutputCache directive is quite a bit of an "all-or-nothing" approach to page caching. There is a "VaryByContol" attribute to the directive, however, that can only be used in ASP.NET user controls, rather an a complete ASP.NET web page.

From your question, it sounds moer like you need to investigate partial page caching. Either that or a mechanism to invalidate the cache when some event occurs. This is usually done by adding a "cache dependency".

For that, the following links should help:

Caching Portions of an ASP.NET Page
Tip/Trick: Implement "Donut Caching" with the ASP.NET 2.0 Output Cache Substitution Feature
Programmatically Removing a Page from the OutputCache

CraigTP
+2  A: 

Right, the thing is you're varying by NO parameter so the first request's response html is cached and served for the next 10 minutes (in theory). If you want to cache GETs but process different POSTs you should vary by your POST params.

Let me give you an example. You have a text input used to send an email with its content on POST. If you vary by that input name, each request within the caching time span with different values for that text input would hit your handler and process sending the email.

On the other side you could vary by * but then you'd lose kernel mode caching.

Can you post an example hot to use my post parameters as a VaryByParam?
lnetanel
sure, <%@ OutputCache Duration="600" VaryByParam="YourPostParam1, YourPostParam2, (any GET params also), ..."%>
Just figured this out before finding this post - we've actually had an issue with a live rollout because we had VaryByParam set to "none" where pages posted back to themselves!
James Marshall