Adding Cache safe links to a Grunt build in ASP.NET Core 1.0

The post shows how to add cache safe links and scripts to a HTML file using grunt in a ASP.NET Core 1.0 application. The post uses the grunt build configuration from this blog, ( ASP.NET Core 1.0 Typescript AngularJS application with a grunt production configuration ).


2016.07.01: Updated to ASP.NET Core 1.0 RTM
2016.06.11: Updated to ASP.NET Core 1.0 RC2
2015.11.18: Updated to ASP.NET Core 1.0 RC1
2015.10.20: Updated to ASP.NET Core 1.0 beta 8


When updating the production deployment, or continuous builds, in a web application, the old versions of the scripts and the CSS files will still be used, because these are saved in the client’s browser cache and the new ones have the same URLs. To solve this, a version hash is used to force the client to load the new files. The following configuration changes the links for every build and every CSS, script file used by the client. If you have a web application with lots of users, this is not a good strategy as you only want the browser to download the new changed files and not all the files. For example, the vendor CSS, script files will not change in every version.

It might also be helpful that the build version number is used and not a random hash for production releases. This would help with issue tracking.


In the application package.json file, the npm grunt-cache-control package is added. Visual Studio 2015 automatically downloads this for you.

    "name": "package",
    "version": "1.0.0",
    "private": true,
    "devDependencies": {
        "grunt": "0.4.5",
        "grunt-bower-install": "^1.6.0",
        "grunt-bower-task": "0.4.0",
        "grunt-contrib-cssmin": "^0.12.2",
        "grunt-contrib-uglify": "0.9.1",
        "grunt-contrib-watch": "0.6.1",
        "grunt-contrib-concat": "0.5.1",
        "uglify-js": "2.4.20",
        "grunt-ts": "4.0.1",
        "grunt-cache-control": "0.2.5"

This grunt-cache-control npm package can then be used in the grunt file.


A random hash string is created using the code from rob lauren’s blog. Thanks for this. This hash is then added to the version property. This creates a new random number for every build. This ensures that new links and scripts are always used in the browser with each build and not just with each version. This helps with continuous builds.

        hash: '<%= ((new Date()).valueOf().toString()) + (Math.floor((Math.random()*1000000)+1).toString()) %>',          
        cache_control: {
            your_target: {
                source: ['wwwroot/index.html'],
                options: {
                    version: "<%= hash %>",
                    links: true,
                    scripts: true,
                    replace: true


The cache_control task is then added to the grunt registerTask which groups the different tasks together for the build.

      [ 'ts', 

     [ 'ts', 

The grunt task now creates new links with every grunt build.


The new links are added in the index.html file.

<!DOCTYPE html>
        <meta charset="utf-8" />
        <title>Demo typescript ASP.NET5</title>
        <link href="lib/mycode.min.css?v=1442604838788656950" rel="stylesheet" />
        <link href="lib/vendor.min.css?v=1442604838788656950" rel="stylesheet" />
        <div ng-app="myapp">
            <div ui-view></div>

        <script type="text/javascript" src="lib/vendor.min.js?v=1442604838788656950"></script>
        <script type="text/javascript" src="lib/mycode.min.js?v=1442604838788656950"></script>


This is also a good solution if using Visual Studio 2013, because the required files have to be added to the cs project file. If new js and css are created each time, the csproj file would also need to be changed. This is not required with this configuration solving the client browser cache problem.


One comment

  1. Thanks for the link back to our blog Damien!

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: