How the JavaScript MVC version includes:

Possible duplicate:
force browsers to fetch the latest js and css files in asp.net app

I'm working with different code, so I don't know the whole picture, and I don't even know MVC, but here's the problem ...

Site.Master has

<%= Html.IncludeJs("ProductPartial")%>

      

which produces this line in the final caption

<script type="text/javascript" src="/Scripts/release/ProductPartial.js"></script>

      

I made some changes to the JS file, but the old one is explicitly cached by the browser, so the changes won't show up until the user refreshes. The usual workaround is to add a version tag to the end of the original script path, but I'm not sure how to do this in this case.

Any suggestions?

+2


a source to share


5 answers


It turns out IncludeJs is a helper method to automatically include compressed JS files in release mode: LINK .



So I just need to modify this method slightly to include the version number. Sorry for the confusion.

0


a source


Why not write your own Html helper extension method and print the version number of your application assembly? Something along these lines should do the trick:

public static MvcHtmlString IncludeVersionedJs(this HtmlHelper helper, string filename)
{
    var version = Assembly.GetExecutingAssembly().GetName().Version;
    return MvcHtmlString.Create(filename + "?v=" + version);
}

      



Then you can increment the build version number every time you release a new version to your users and their caches will be invalid in the application.

+4


a source


I solved this by applying the last modified timestamp as a request parameter to the scripts.

I did it with an extension method and used it in my CSHTML files. Note. this implementation caches the timestamp for 1 minute, so we don't partition the disk very much.

Here's a way to expand:

 public static class JavascriptExtension {
    public static MvcHtmlString IncludeVersionedJs(this HtmlHelper helper, string filename) {
        string version = GetVersion(helper, filename);
        return MvcHtmlString.Create("<script type='text/javascript' src='" + filename + version + "'></script>");
    }

    private static string GetVersion(this HtmlHelper helper, string filename)
    {
        var context = helper.ViewContext.RequestContext.HttpContext;

        if (context.Cache[filename] == null) {
            var physicalPath = context.Server.MapPath(filename);
            var version = "?v=" +
              new System.IO.FileInfo(physicalPath).LastWriteTime
                .ToString("yyyyMMddhhmmss");
            context.Cache.Add(physicalPath, version, null,
              DateTime.Now.AddMinutes(1), TimeSpan.Zero,
              CacheItemPriority.Normal, null);
            context.Cache[physicalPath] = version;
            return version;
        }
        else {
            return context.Cache[filename] as string;
        }
    }

      

And then on the CSHTML page:

 @Html.IncludeVersionedJs("/MyJavascriptFile.js")

      

In the rendered HTML, it looks like:

 <script type='text/javascript' src='/MyJavascriptFile.ks?20111129120000'></script>

      

+4


a source


+1


a source


The strategy of your version is really not important. As long as the filename is different, the browser will be forced to fetch a new script. So even this would work:

<%= Html.IncludeJs("ProductPartialv1")%>

ProductPartialv1.js

      

I use this technique for important JavaScript and CSS changes (CSS is also cached by the browser) - so I update the template to use a newer version, and I'm confident that if new HTML is used, as well as the new script and CSS file.

This is "in action" at http://www.the-mag.me.uk/ - where I just increment the numeric suffix in the files.

0


a source







All Articles