views:

290

answers:

1

Hello,

I have a question related to cache invalidation techniques... I am trying to implement a mechanism for my website, that automatically invalidates browser cache (css, images...). I want to be able to programatically invalidate browser cache, whenever I update the website (change images or styles);

For example: for the current release, among others, the css and some of the images have changed. In this situation I want that after the update is finished, when a user performs a request to the website, his browser's cache to get automatically invalidated, thus forcing the re-download of the new images and styles. This should be done only for the client's first request... the following ones should be retrieved from cache (so setting the no-cache pragma is out of the question).

Here's what i've tried: in the BeginRequest event handler, I added the following lines: Response.Cache.SetCacheability(HttpCacheability.ServerAndPrivate); Response.Cache.SetETag("\"e111293b17594f1487d136ea7e9314ac\"");

this sets the ETag in the response headers. I figured that if I change this ETag at each release, and set it at each request, the cache will be invalidated, but it seems that it is not. I used Live HTTP headers to see the results and the ETAG is correctly set up for the response, but the css and images are still taken from cache....

Any ideas of how I could accomplish this, or if it can be accomplished at all?

Thanks in advance!

+1  A: 

I have run into issues like this in the past. Unfortunately I couldn't find a really nice way to accomplish this so I had to come up with a workaround. I was only dealing with this issue for CSS files so I added an extra querystring parameter to every CSS reference, for example

 <link rel="stylesheet" type="text/css" 
       href="default.css?buildnumber=<%= Buildnumber %>" />

The build number gets incremented with each release so the browser was forced to go look for this new file. Not an ideal solution, but it worked without a hitch.

Bob
that is a good idea, but what about the images... it's not so easy to place a query param to each image refference in the project... thanks for the answer
GeoXYZ
This should still work for images. Perhaps if all of your images are server controls you could override a page event, maybe onrender, and find all images and append the extra url parameter
Bob
yes, i know i could do that, but it's not a good practice... first of all, think that i would have to do this on all pages with images on them (because not only the masterpage has images, but the user controls also have images inside); second of all, in order to automate this process (not to have to adapt the code whenever i add another image control on the page), i would have to iterate through the page controls and find image controls only and modify the imageurl property... and this is very time consuming especially if the hit count for that control is high, thus inducing a performance hit.
GeoXYZ
i thought of a new solution,but i still don't like it;at each session start,i could check for the existence of a cookie (with release number for example),and if not found set the Cache.Expires to -1 thus forcing to get the imgs and css from server instead of cache,and then create this cookie so that the next time it won''t enter this block of code; and then at next call if cookie exists, set the Expires to a longer period (2 months for example).but i don't like the cookie check at each session start and second, it will only work for first page visited (if code is placed on session start event)
GeoXYZ