views:

227

answers:

4

I have some css files that need to be generated dynamically (why is complicated, but it's necessary). The easy solution is to change the files to aspx files, and use <%= %> tags as needed to inject the values I want.

This works fine, until we get to caching. It seems that the browser and server refuse to cache the file. I've tried manipulating the various http cache headers, but the browser always re-gets the file on each page load. The server always responds with HTTP 200 (and the correct content), rather than with a 304 (file unchanged).

How can I convince the browser and the server to cache these dynamic css files?

Example consuming file:

<html> <head> <link href="/style.aspx" type="text/css" rel="stylesheet"/> ...

Example style sheet, with cache header manipulation (omitting dynamic part of file):

<%@ Page Language="C#" ContentType="text/css" EnableSessionState="False" %>
<% Response.Cache.SetLastModified(new DateTime(2009, 11, 18, 10, 1, 0)); Response.Cache.SetMaxAge(TimeSpan.FromDays(30)); Response.Cache.SetETag("4ffff353ff67ff1:0"); %>
...css here...

The request headers to the server includes the following:

If-Modified-Since Wed, 18 Nov 2009 18:01:00 GMT
Cache-Control max-age=0

And the related server response headers are:

Cache-Control private, max-age=2592000
Last-Modified Wed, 18 Nov 2009 18:01:00 GMT
Date Wed, 18 Nov 2009 19:36:07 GMT

Any ideas?

A: 

Have you tried Response.SetExpires()? This is a little simpler than setting the mod date and max age - maybe your browser will like it better.

Ray
Unfortunately Response.Cache.SetExpires(...) was unsuccessful. The browser is still requesting the file.
Ken Mason
Is the ETag string the same every time? Have you tried it without the ETag (using only SetExpires() or your original code)?
Ray
Have you tried inspecting the headers sent by your server for the first request? Does it contain an expires header?
Salman A
Yes, I made sure the ETag was the same every time, and it still refused to cache it. I also tried using only SetExpires(), and that was ineffective.Yes, the response headers fro the first request contained the expired header as expected when using the SetExpires() method. The headers all seem to be in order.
Ken Mason
Is the Request URI completely unchanged on every request? Is it always the same domain?
Pekka
Yesm and yes. The URI is identical with every request, including the FQDN.
Ken Mason
+1  A: 

How about caching the .aspx page that is acting as a css file using something like this:

<%@ OutputCache Duration="60" Location="Client" VaryByParam="None" %>

How to cache in ASP.NET by using Visual C# .NET

Bertine
Thanks, I had not seen that link. Unfortunately that didn't work either. That's what I expected, since the OutputCache tag ultimately amounts to calls to Response.Cache.*(), which is what I've already been trying.
Ken Mason
+1  A: 

Did you try your caching settings (and result) on a regular HTML page? I mean, are you sure it's a CSS issue, rather than a regular HTML page?

Ron Klein
A: 

edit: Didn't realize this was such an old question, hopefully this still helps someone out there.

Can you pass a bogus, randomly generated querystring to force the recache?

For example:

<link href="<%=sStyleSheet%>" type="text/css" rel="stylesheet" />

and then something like this in your codebehind

Random random = new Random();
int num = random.Next(100000);
string sStyleSheet = "/style.aspx?q=" + num.ToString();
JN Web