Category Archives

8 Articles

Posted by .Ronald on

Prevent caching of stylesheet and javascript files

First something about caching

The numerous caching options you have in ASP.NET (MVC) are mainly focused on data and page output caching. But caching also occurs at the webserver, network and browser level.  These you can’t always control from within your code.

When your content leaves your application, it is processed by the webserver, depending on the server and version it has numerous options to control how and when it is cached. When your content is processed by the webserver and sent to the browser, there is also the network that can control the caching, namely proxy and web acceleration servers. Finally the content arrives in the browser and the browser itself has also numerous options related to caching. Generally spoken, they all use the same parameters, or at least some of them, to determine when, what and how long the content should be cached.

How does this caching work? Generally spoken, following rules apply:

  1. If the response header says not to cache, it doesn’t cache
  2. If we use a secure or authenticated transfer, like HTTPS, it doesn’t cache either
  3. If the cache expiring time or any other age-controlling header says it’s still ‘fresh’, it doesn’t cache
  4. If there’s an old version in the cache, the server will be asked to validate the version.  If the version is still good, it is served from the cache.
  5. Sometimes when the server cannot be reached due to network failure or disconnectivity, the content is also directly served from the cache.

Then what parameters are used, and how are they used?

  • HTTP Headers: these are sent in the request, but are not visible in the content
    • Expires: tells the cache how long the content stays fresh. After that time, the cache will always check back with the server. It uses an HTTP date in Greenwich Mean Time (GMT), any other or invalid format will be interpreted as in the pas and makes the content uncachable.  For static data you can set a time in the very far future, for highly dynamic content, you can set a time much closer, or even in the past to have the cache refresh the content more often or at every request.
    • Cache-Control: In response to some of the drawbacks of the Expired header, the Cache-Control header class was introduced. It includes (some, not all):
      • max-age=[seconds]
      • public / private
      • no-cache / no-store
      • must-revalidate
    • Pragma: no-cache: the HTTP specifications aren’t clear of what it means, so don’t rely on it, use the ones above
  • HTML meta tags: Unlike HTTP Headers, HTML meta tags are present in the visible content, more precisely in the <HEAD> section of your HTML page. A huge drawback of the us of HTML meta tags is, is that they can only be interpreted by browsers, and not all of them use them like you would expect. So prefer HTTP headers over HTML meta tags

A great Caching Tutorial can be found here: http://www.mnot.net/cache_docs/, and another one here: Save Some Cash: Optimize Your Browser Cache

An easy solution

Now, all of the caching systems rely in some way on the full request string to identify the content that is being cached.

So, the easiest solution would be to request a new unique URL every time the resource has changed, with a new version number.

How we do it in ASP.NET MVC

ASP.NET MVC (and ASP.NET Webforms also) doesn’t generate a new version number automatically.  You need to tell it to do so in the AssemblyInfo.cs file.  After a default project setup it contains a line like:

[assembly: AssemblyVersion("1.0.0.0")]

The version number is a four-part string with the following format: <major version>.<minor version>.<build number>.<revision>.  You usually set the major and minor version manually, as they are used as the type library version number when the assembly is exported, and don’t (need to) care of the build and revision number.  Well, now we do.

When you change this line to (or add it if it doesn’t exist):

[assembly: AssemblyVersion("1.0.*")]

We tell the compiler to generate a build and revision number for us. The generated build number is the number of days since 1-01-2000 (so 9-08-2010 gives 3873) and the revision number is the number of two second intervals since midnight local time (so a build at 11:59:12 gives 19776).

Now we have instructed our application to generate a new unique build number for us with every build, and every (possible) change of a resource, we can use this number as a unique parameter value in the URL of the the resource.

First we need to pass this version number from controller to view.  In the constructor of the (base)controller we put the version number in the ViewData Dictionary. With the ViewData you easily can pass data from the controller to the view using a key-value pattern.

protected BaseController(){
ViewData["version"] = Assembly.GetExecutingAssembly().GetName().Version;
}

And finally in the view, all you need to do is append this version number to the URL of the files you want to be prevented from caching:

<script type="text/javascript" language="javascript" src="<%: Url.Content("~/Scripts/commonFunctions.js?" + ViewData["version"]) %>"></script>

This makes sure we have a unique URL for our resources and they are not cached by the browser or a proxy.

Of course, like stated above, there are other ways of preventing files from being cached anywhere between the server and the browser, but the advantage of this method is that you don’t need to poke around in IIS settings (in case when you don’t have access to it) and you can define when and which version of the file you want to be cached.  And you can of course use any other method to generate a unique URL.

One more remark: When building a multi-tier application, make sure you set the version number in the AssemblyInfo.cs of the project where you use it, meaning, that if you put your base controller in a shared assembly, you need to specify the version number in the shared assembly project.

Posted by .Ronald on

50 Extremely Useful And Powerful CSS Tools

We love useful stuff. For months, we have been bookmarking interesting, useful and creative CSS tools and related resources. We have been contacting developers, encouraging them to improve their tools and release their handy little apps to the public. Last year we prepared and published some of them in a series of smashing posts about CSS. Now again is the time to give these tools the attention they deserve. Big thanks to all designers and developers who contributed to the design community over the last months and years. We — our community and the design community — truly appreciate your efforts.

Below, we present 50 extremely useful CSS tools, generators, templates and resources. We did not include “traditional” CSS tools, such as Firebug or the Web Developer extension, but tried to focus on rather unknown tools that are definitely worth a look. Some tools are new and some are old, but hopefully everybody will find a couple of new useful or at least inspiring tools.

We strongly encourage you to develop these tools further, build on the ideas presented here, release new tools for the public and let us know about them. We would love to feature your handy tool in our next review.

Smashing Magazine50 Extremely Useful And Powerful CSS Tools

Posted by .Ronald on

Character encoding

Character encoding can be wickedly difficult to get right, especially when you want to start using UTF-8. It seems there is always at least one part of the chain from your brain to the end user’s browser that has problems with UTF-8.

Two articles that try explain character encoding are The Definitive Guide to Web Character Encoding and UTF-8: The Secret of Character Encoding. I won’t pretend to fully grasp character encoding, but after reading these articles I believe I at least understand it a little better.

456 Berea StreetCharacter encoding

Posted by .Ronald on

Migrate apps from Internet Explorer to Mozilla

When Netscape started the Mozilla browser, it made the conscious decision to support W3C standards. As a result, Mozilla is not fully backwards-compatible with Netscape Navigator 4.x and Microsoft Internet Explorer legacy code; for example, Mozilla does not support as I will discuss later. Browsers, like Internet Explorer 4, that were built before the conception of W3C standards inherited many quirks. In this article, I will describe Mozilla’s quirks mode, which provides strong backwards HTML compatibility with Internet Explorer and other legacy browsers.

MDCMigrate apps from Internet Explorer to Mozilla

Posted by .Ronald on

Testing IE Versions Just Got a Little Easier

Testing your sites on different versions of Internet Explorer has always been notoriously difficult mainly due to the fact that Microsoft prevents you from running to different versions of the browser in Windows. Sure there have been solutions to get around this limitation but in my experience, they’ve always caused unexpected results and instability for the operating system or required you to run a VM. Not ideal.

AjaxianTesting IE Versions Just Got a Little Easier

Posted by .Ronald on

Dust-Me Selectors Version 2.0

After many months of toiling in our secret underground laboratories, Dust-Me Selectors Version 2.0 is finally here!
If you’re one of the many people who made suggestions or commented on the original version, you’ll be pleased to know that the new version incorporates everything you asked for and more.
It was quite a challenge to bring all this together, particularly since Mozilla’s documentation is so … er … erratic (in fact for some functionality I had to look in Firefox’s source code just to figure out how it’s done!) But there’s nothing like a challenge to exercise the mind, and I think you’ll agree that the final result is well worth the gritty struggle.

SitePoint Blogs Dust-Me Selectors Version 2.0