A couple of weeks ago I had the requirement to enable ASP.NET output caching programmatically rather than declarative using the <%@ OutputCache … %> tag.
I tried to follow the hints in the following KB: https://support.microsoft.com/default.aspx?id=323290. Actually what I found is that these procedure do not really work as expected.
Especially the following in which I was interested:
Declarative Approach:
<%@ OutputCache Duration="60" Location="Server" VaryByParam="None" %>
Programmatic Approach:
Response.Cache.SetExpires(DateTime.Now.AddSeconds(60));
Response.Cache.SetCacheability(HttpCacheability.Server);
What I found is that when using CTRL-F5 the declarative approach always returned the cached version but the programmatic approach returned a new version from the server. Not what I was looking for as I needed to control the amount of time but without affecting any other caching features.
Finally someone in the ASP.NET caching newsgroup was able to point me to the solution for this. There is an extra property that needs to be set to ensure that the cache gets persisted through CTRL-F5.
Here is now the complete code:
Response.Cache.SetExpires(DateTime.Now.AddSeconds(60));
Response.Cache.SetCacheability(HttpCacheability.Server);
Response.Cache.SetValidUntilExpires(true);
Permalink
Awesome, we were looking for a way to do this. When we were looking into the same thing we also found there is a protected function on the System.Web.UI.Page object that allows all the caching params to be set. It is called InitOutputCache.
Intellisense will not display it because it is set to EditorBrowsableState.Never, but this is what the JIT will actually uses when it compiles the page (if you put an error in a runat server script block and look at the full compilation source).
I don’t like having to use it because it is not intended to be called directly (according to MSDN), but I am not sure how else to be able to set the cache to vary by param programmatically. Would it be better to construct the HttpCacheability and HttpCachePolicy objects manually rather then rely on InitOutputCache method to do it? Any ideas would be appreciated.
Permalink
After a little more looking into it…
<%@ OutputCache Duration="60" Location="Server" VaryByParam="None" %>
==
this.InitOutputCache(60, null, null, OutputCacheLocation.Server, null);
==
HttpCachePolicy policy = this.Response.Cache;
policy.SetCacheability(HttpCacheability.Server);
policy.SetExpires(this.Context.Timestamp.AddSeconds((double)60));
policy.SetMaxAge(new TimeSpan(0, 0, 60));
policy.SetValidUntilExpires(true);
policy.SetLastModified(this.Context.Timestamp);
policy.VaryByParams.IgnoreParams = true;
If you need to vary by params these can just be set on the policy and ignore params would need to be set to false.
Thanks for us pointing in the right direction on all of this.
Permalink
Hi.
Thanks. for this interesting article.
How can we setup a VaryByParam, Please ?
Permalink
VaryByParam can be configured like this:
Response.Cache.VaryByParams["City"] = true;
Permalink
Thanks Stefan. Saved me a lot of time.
Permalink
how can we configure VaryByControl in programatic approch?