views:

2128

answers:

7

If you look at Stackoverflow.com's source you'll see the reference to their css file is:

<link href="/Content/all.min.css?v=2383" rel="stylesheet" type="text/css" />

How is this done so they can pass a version via query string and have the correct CSS file served up?

+5  A: 

See this earlier question for an explanation: What does ‘?’ do in a Css link?

Paul Dixon
So what is it in this case? Dynamically generated?
Simucal
Almost certainly not, as I described in that answer
Paul Dixon
Sorry, my mistake.
Simucal
+1  A: 

Its so your browser does not cache the css file. And using the version number is handy since the css file could have changed in each version.

It's not a way to call a correct css file. The file is always the same, but the version number makes your browser think otherwise and fetch it again.

Ólafur Waage
I'm not really asking why, although I appreciate that. I'm asking how. How is that query string value translated into an actual file.
Simucal
So when the file is copied over there is that its physical file name? "all.min.css?v=2383" ? I understand that it is used to prevent caching
Simucal
It has nothing to do with the file. Its just added in the code of the page. The filename is still all.min.css
Ólafur Waage
And this doesn’t really prevent caching but every time the number is changed the page is loaded again because it’s a new URL. The old URLs remain cached, though.
Bombe
+2  A: 

This (PHP example) article explain you the idea behind it. Basically, you could happend the timestamp of the last time you modified the file. This way everytime you change your CSS, the querystring will change and "forcing" the browser to download the new version. This is valid for both CSS and JS files.

A ASP.NET sample is this:

public static string GetBreaker(string fileName)
{
    string cacheBreaker = null;
    try
    {
        if (fileName.StartsWith("~"))
        {
            fileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName.Remove(0));
        }
        cacheBreaker = File.GetLastWriteTime(fileName).ToFileTime().ToString();
    }
    catch { }

    return string.IsNullOrEmpty(cacheBreaker) ? string.Empty : string.Format("?cachebreaker={0}", cacheBreaker);
}

And you call this method in your MasterPage in this way:

<link href="<%= this.ResolveClientUrl("~/CSS/style.css") %><%=CacheBreaker.GetBreaker("~/CSS/style.css") %>"
            rel="stylesheet" type="text/css" />
Davide Vosti
+1  A: 

If you want to know how it is done, they shortly mentioned it in a previous blog entry: it is done automatically by their build process. See this blog post (3rd bullet point).

Unfortunately there are no details, but maybe you can get more information by commenting that blog post or by contacting the stackoverflow team.

M4N
A: 

public static string GetBreaker(string fileName) { string cacheBreaker = null; try { if (fileName.StartsWith("~")) { fileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName.Remove(0)); } cacheBreaker = File.GetLastWriteTime(fileName).ToFileTime().ToString(); } catch { }

return string.IsNullOrEmpty(cacheBreaker) ? string.Empty : string.Format("?cachebreaker={0}", cacheBreaker);

}

<%=CacheBreaker.GetBreaker("~/CSS/style.css") %>" rel="stylesheet" type="text/css" />

where to add these code, in which section ..

A: 

It could be easier just to change the name of the file each time it is changed to achieve the same effect.

file001.css
file002.css

I have a feeling that keeping the filename the same and appending ?ver=1234 is to make source control easier.

Bing
A: 

I blogged an example of how to do this very easily when using the SparkViewEngine here

Corey Kaylor