gro*_*wse 47 caching bundle asp.net-mvc-4
我有一个MVC应用程序,我正在使用StyleBundle该类来渲染CSS文件,如下所示:
bundles.Add(new StyleBundle("~/bundles/css").Include("~/Content/*.css"));
Run Code Online (Sandbox Code Playgroud)
Debug我遇到的问题是,在模式下,CSS网址是单独呈现出来的,我有一个网络代理,可以积极地缓存这些网址.在Release模式中,我知道查询字符串被添加到最终URL以使每个版本的任何缓存无效.
是否可以配置StyleBundle在Debug模式中添加随机查询字符串以产生以下输出以解决缓存问题?
<link href="/stylesheet.css?random=some_random_string" rel="stylesheet"/>
Run Code Online (Sandbox Code Playgroud)
bin*_*les 46
您可以创建自定义IBundleTransform类来执行此操作.这是一个使用文件内容的散列附加av = [filehash]参数的示例.
public class FileHashVersionBundleTransform: IBundleTransform
{
public void Process(BundleContext context, BundleResponse response)
{
foreach(var file in response.Files)
{
using(FileStream fs = File.OpenRead(HostingEnvironment.MapPath(file.IncludedVirtualPath)))
{
//get hash of file contents
byte[] fileHash = new SHA256Managed().ComputeHash(fs);
//encode file hash as a query string param
string version = HttpServerUtility.UrlTokenEncode(fileHash);
file.IncludedVirtualPath = string.Concat(file.IncludedVirtualPath, "?v=", version);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以通过将类添加到捆绑包的Transforms集合来注册该类.
new StyleBundle("...").Transforms.Add(new FileHashVersionBundleTransform());
Run Code Online (Sandbox Code Playgroud)
现在版本号只会在文件内容改变时改变.
H D*_*Dog 41
你只需要一个独特的字符串.它不一定是哈希.我们使用文件的LastModified日期并从那里获取Ticks.正如@Todd所说,打开和阅读文件很昂贵.刻度足以输出在文件更改时更改的唯一编号.
internal static class BundleExtensions
{
public static Bundle WithLastModifiedToken(this Bundle sb)
{
sb.Transforms.Add(new LastModifiedBundleTransform());
return sb;
}
public class LastModifiedBundleTransform : IBundleTransform
{
public void Process(BundleContext context, BundleResponse response)
{
foreach (var file in response.Files)
{
var lastWrite = File.GetLastWriteTime(HostingEnvironment.MapPath(file.IncludedVirtualPath)).Ticks.ToString();
file.IncludedVirtualPath = string.Concat(file.IncludedVirtualPath, "?v=", lastWrite);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
以及如何使用它:
bundles.Add(new StyleBundle("~/bundles/css")
.Include("~/Content/*.css")
.WithLastModifiedToken());
Run Code Online (Sandbox Code Playgroud)
这就是MVC所写的:
<link href="bundles/css/site.css?v=635983900813469054" rel="stylesheet"/>
Run Code Online (Sandbox Code Playgroud)
也适用于Script bundle.
Raf*_*afe 13
这个库可以在调试模式下将缓存破坏哈希添加到您的包文件中,以及其他一些缓存破坏的东西:https://github.com/kemmis/System.Web.Optimization.HashCache
将所有捆绑包添加到集合后,在BundlesCollection实例上执行ApplyHashCache()扩展方法 .
BundleTable.Bundles.ApplyHashCache();
Run Code Online (Sandbox Code Playgroud)
创建HashCacheTransform的实例并将其添加到要应用HashCache的bundle实例.
var myBundle = new ScriptBundle("~/bundle_virtual_path").Include("~/scripts/jsfile.js");
myBundle.Transforms.Add(new HashCacheTransform());
Run Code Online (Sandbox Code Playgroud)
我有同样的问题,但升级后在客户端浏览器中使用缓存版本.我的解决方案是将调用包装@Styles.Render("~/Content/css")在我自己的渲染器中,该渲染器将我们的版本号附加在查询字符串中,如下所示:
public static IHtmlString RenderCacheSafe(string path)
{
var html = Styles.Render(path);
var version = VersionHelper.GetVersion();
var stringContent = html.ToString();
// The version should be inserted just before the closing quotation mark of the href attribute.
var versionedHtml = stringContent.Replace("\" rel=", string.Format("?v={0}\" rel=", version));
return new HtmlString(versionedHtml);
}
Run Code Online (Sandbox Code Playgroud)
然后在视图中我喜欢这样:
@RenderHelpers.RenderCacheSafe("~/Content/css")
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
14972 次 |
| 最近记录: |