How to version MVC JavaScript includes [duplicate]
Possible Duplicate:
force browsers to get latest js and css files in asp.net application
I'm working with someone else's code, so I don't know the whole picture, and I don't even know MVC that well, but here's the problem...
In Site.Master开发者_Go百科 there's a
<%= Html.IncludeJs("ProductPartial")%>
which produces this line in the final mark-up
<script type="text/javascript" src="/Scripts/release/ProductPartial.js"></script>
I made some changes in the JS file, but the old one is obviously cached by the browser, so the changes won't show up until the user refreshes. The usual workaround is to add a version tag at the end of the script source path, but I'm not sure how to do that in this case.
Any suggestions?
Why not write your own Html helper extension method, and make it output 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);
}
You can then increment the version number of the assembly whenever you release a new version to your users, and their caches will be invalidated across the application.
I solved this by tacking a last modified timestamp as a query parameter to the scripts.
I did this with an extension method, and using it in my CSHTML files. Note: this implementation caches the timestamp for 1 minute so we don't thrash the disk quite so much.
Here is the extension method:
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 in the CSHTML page:
@Html.IncludeVersionedJs("/MyJavascriptFile.js")
In the rendered HTML, this appears as:
<script type='text/javascript' src='/MyJavascriptFile.ks?20111129120000'></script>
Here are some links already on this topic:
Why do some websites access specific versions of a CSS or JavaScript file using GET parameters?
force browsers to get latest js and css files in asp.net application
Your version strategy really isn't important. As long as the file name is different, the browser will be forced to get the new script. So even this would work:
<%= Html.IncludeJs("ProductPartialv1")%>
ProductPartialv1.js
I have been using this technique for important JavaScript and CSS changes (CSS is also cached by the browser) - so I update the template to use the newer version and I'm safe in the knowledge that if the new HTML is used, so is the new script and CSS file.
It is "in action" on http://www.the-mag.me.uk/ - where I just increment a numeric suffix on the files.
It turns out IncludeJs is a helper method for automatically including compressed JS files when in release mode: LINK.
So I just have to modify that method a bit to include a version number. Sorry about the confusion.
精彩评论