如何强制BundleCollection刷新在MVC4缓存脚本包 [英] How to force BundleCollection to flush cached script bundles in MVC4

查看:1442
本文介绍了如何强制BundleCollection刷新在MVC4缓存脚本包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

...或我如何学会停止担忧,并只写对无证完全的API code微软的。是否有官方的 System.Web.Optimization 发布任何实际的文档? 因为我肯定找不到任何,有没有XML文档,所有的博客文章指RC API,它是完全不同的。安美居..

... or how I learned to stop worrying and just write code against completely undocumented APIs from Microsoft. Is there any actual documentation of the official System.Web.Optimization release? 'cuz I sure can't find any, there's no XML docs, and all the blog posts refer to the RC API which is substantially different. Anyhoo..

我写了一些code自动解决的javascript依赖和我从这些依赖动态创建包。一切都很正常,但如果编辑脚本或以其他方式会影响一个包,无需重新启动应用程序的变化,这些变化将不会反映。所以我增加了一个选项来禁用依赖于开发利用缓存。

I am writing some code to automatically resolve javascript dependencies and am creating bundles on the fly from those dependencies. Everything works great, except if you edit scripts or otherwise make changes that would affect a bundle without restarting the application, the changes won't be reflected. So I added an option to disable caching of the dependencies for use in development.

不过,显然 BundleTables 缓存URL的即使捆绑集合发生更改的。例如,在我自己的code,当我想重新创建一个包我做这样的事情:

However, apparently BundleTables caches the URL even if the bundle collection has changed. For example, in my own code when I want to re-create a bundle I do something like this:

// remove an existing bundle
BundleTable.Bundles.Remove(BundleTable.Bundles.GetBundleFor(bundleAlias));

// recreate it.
var bundle = new ScriptBundle(bundleAlias);

// dependencies is a collection of objects representing scripts, 
// this creates a new bundle from that list. 

foreach (var item in dependencies)
{
    bundle.Include(item.Path);
}

// add the new bundle to the collection

BundleTable.Bundles.Add(bundle);

// bundleAlias is the same alias used previously to create the bundle,
// like "~/mybundle1" 

var bundleUrl = BundleTable.Bundles.ResolveBundleUrl(bundleAlias);

// returns something like "/mybundle1?v=hzBkDmqVAC8R_Nme4OYZ5qoq5fLBIhAGguKa28lYLfQ1"

每当我删除&安培;重新捆绑的与相同的别名的,绝对没有发生的情况: bundleUrl ResolveBundleUrl 返回是和以前一样我删除&安培;重新捆绑。由相同的我的意思是该内容散列是不变,以反映该包的新的内容。

Whenever I remove & recreate a bundle with the same alias, absolutely nothing happens: the bundleUrl returned from ResolveBundleUrl is the same as before I removed & recreated the bundle. By "the same" I mean that the content hash is unchanged to reflect the new contents of the bundle.

修改的......实际上,它比这更糟糕。在捆绑本身的是某种捆绑收集外缓存。如果我只是生成我自己的随机哈希prevent缓存这些脚本的浏览器,ASP.NET返回的旧脚本的。所以,很显然,除去 BundleTable.Bundles 捆绑实际上并没有做任何事情。

edit... actually, it's much worse than that. The bundle itself is cached somehow outside of the Bundles collection. If I just generate my own random hash to prevent the browser from caching the script, ASP.NET returns the old script. So, apparently, removing a bundle from BundleTable.Bundles does not actually do anything.

我可以简单地改变别名解决这个问题,这是发展的不错,但我不喜欢这个主意,因为这意味着要么我有每个页面加载后脱precate别名,或有生长在大小上的每个页面加载一个BundleCollection。如果您在生产环境中离开了这个上,那将是一场灾难。

I can simply change the alias to get around this problem, and that is OK for development, but I don't like that idea since it means either I have to deprecate aliases after each page load, or have a BundleCollection that grows in size on every page load. If you left this on in a production environment, it would be a disaster.

如此看来,当一个脚本服务,它就会缓存独立于实际 BundleTables.Bundles 的对象。所以,如果你重新使用URL,即使你删除它称作再使用它之前,它在它的缓存任何的响应,并捆绑改变捆绑对象不刷新缓存 - 因此,只有的新的的项目(或更确切地说,新项目使用不同的名称)将被使用。

So it seems that when a script is served, it gets cached independent of the actual BundleTables.Bundles object. So if you re-use a URL, even if you've removed the bundle that it referred to before reusing it, it responds with whatever's in its cache, and altering the Bundles object does not flush the cache -- so only new items (or rather, new items with a different name) would ever be used.

行为似乎很奇怪......从集合中移除的东西应该从缓存中删除。但事实并非如此。必须有刷新这个缓存的方式,并使用其中的 BundleCollection 不是什么缓存为首次访问该软件包的当前内容。

The behavior seems odd... removing something from the collection should remove it from the cache. But it doesn't. There must be a way to flush this cache and have it use the current contents of the BundleCollection instead of what it cached when that bundle was first accessed.

任何想法,我会怎么做呢?

Any idea how I would do this?

有是有一个未知的目的,这个 ResetAll 方法,但它只是打破了事情反正,这样是不是。

There is this ResetAll method which has an unknown purpose but it just breaks things anyway so that isn't it.

推荐答案

我们听到的文档你的痛苦,遗憾的是该功能还在不断变化相当快,并且生成文档具有一定的滞后性,并且几乎可以立即过时。 里克的博客文章是最新的,而我试图回答的问题这里也为在此期间小号$ p $垫当前信息。目前,我们正在建立我们的官方codePLEX网站,这将有始终是当前文档的过程。

We hear your pain on documentation, unfortunately this feature is still changing quite fast, and generating documentation has some lag, and can be outdated almost immediately. Rick's blog post is up to date, and I've tried to answer questions here as well to spread current info in the meantime. We are currently in the process of setting up our official codeplex site which will have always current documentation.

现在在问候你如何刷新具体问题束形成的高速缓存。

Now in regards to your specific issue of how to flush bundles form the cache.


  1. 我们使用存储要求关闭该包的URL,即 Context.Cache [System.Web.Optimization.Bundle的生成的密钥ASP.NET缓存里面捆绑响应:〜 /包/ jQuery的] 我们还设置缓存对所有被用来产生这种捆绑的文件和目录的相关性。因此,如果任何底层的文件或目录的变化,缓存条目会得到刷新。

  1. We store the bundled response inside of the ASP.NET cache using a key generated off of the bundle url requested, i.e. Context.Cache["System.Web.Optimization.Bundle:~/bundles/jquery"] we also setup cache dependencies against all of the files and directories that were used to generate this bundle. So if any of the underlying files or directories change, the cache entry will get flushed.

我们真的不支持在每个请求的基础上BundleTable / BundleCollection的实时更新。完全支持的方案是,束应用程序启动期间配置的(所以一切都正常工作的Web场的情况下,否则某些捆绑请求将最终成为404的,如果发送到错误的服务器)。看着你code例如,我的猜测是,你正在试图动态修改特定的请求包集合?任何一种捆绑管理/重构应附有一个AppDomain复位,以保证一切都已经正确安装。

We don't really support live updating of the BundleTable/BundleCollection on a per request basis. The fully supported scenario is that bundles are configured during app start(this is so everything works properly in the web farm scenario, otherwise some bundle requests would end up being 404's if sent to the wrong server). Looking at your code example, my guess is that you are trying to modify the bundle collection dynamically on a particular request? Any kind of bundle administration/reconfiguration should be accompanied by an appdomain reset to guarantee everything has been setup correctly.

因此​​要避免不回收您的应用程序域修改您的包定义。你可以自由地修改您的包内的实际文件,这应该会自动检测并生成新的哈希codeS为你包的网址。

So avoid modifying your bundle definitions without recycling your app domain. You are free to modify the actual files inside of your bundles, that should automatically be detected and generate new hashcodes for your bundle urls.

这篇关于如何强制BundleCollection刷新在MVC4缓存脚本包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆