... 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..
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.
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"
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.
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.
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.
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.
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?
There is this ResetAll
method which has an unknown purpose but it just breaks things anyway so that isn't it.