我一直在深入研究ASP.NET MVC的内部功能(原因不同),但仍然无法涵盖所有行为。其中一个我没有做的是subj
其工作方式如下:
如果我绑定了一些文件(例如css文件),框架会检测到这些更改,并且会为新的绑定生成新的id。(以便于浏览器刷新更改),如href="/Content/css?v=qartPE4jGe-l1U0I7kNDZPZzVTdh0kT8VBZZA_uURjI1"。
我真正想了解的是:
-
框架(可能不是MVC,而是.NET的东西)是如何检测到文件被更改的(因为没有目录观察者活动(因为即使web服务器离线,我也可以更改文件)以实时查看文件更改的,而且系统实际上检测到文件内容的更改(我只是试图重新保存文件而不更改其内容,捆绑包编号也没有更改)?(我认为,很明显,系统无法比较每个文件的内容来检测每个请求的变化)。
-
框架在哪里(以及如何)存储当前捆绑包id,以及它如何存储以前的版本(因为以前的捆绑包在访问其URL时仍然可用)?
非常感谢!
ASP.NET优化框架将捆绑包响应缓存在HttpContext.Cache
中,并使用CacheDependency监视捆绑包中的每个文件是否发生更改。这就是为什么更新文件会直接使缓存失效并重新生成捆绑包的原因。
捆绑包文件名是捆绑包内容的散列,它确保在修改任何捆绑包文件时URL都会更改。捆绑包的虚拟路径用作缓存密钥。
库中的相关代码(请注意,这有点过时,但我相信逻辑仍然相同):
internal BundleResponse GetBundleResponse(BundleContext context)
{
// check to see if the bundle response is in the cache
BundleResponse bundleResponse = Bundle.CacheLookup(context);
if (bundleResponse == null || context.EnableInstrumentation)
{
// if not, generate the bundle response and cache it
bundleResponse = this.GenerateBundleResponse(context);
if (context.UseServerCache)
{
this.UpdateCache(context, bundleResponse);
}
}
return bundleResponse;
}
private void UpdateCache(BundleContext context, BundleResponse response)
{
if (context.UseServerCache)
{
// create a list of all the file paths in the bundle
List<string> list = new List<string>();
list.AddRange(
from f in response.Files
select f.FullName);
list.AddRange(context.CacheDependencyDirectories);
string cacheKey = Bundle.GetCacheKey(context.BundleVirtualPath);
// insert the response into the cache with a cache dependency that monitors
// the bundle files for changes
context.HttpContext.Cache.Insert(cacheKey, response, new CacheDependency(list.ToArray()));
context.HttpContext.Response.AddCacheItemDependency(cacheKey);
this._cacheKeys.Add(cacheKey);
}
}
最后,对于旧的捆绑包URL,我想你会发现它们要么是从浏览器缓存中返回的,要么实际上是返回捆绑包的最新版本,因为捆绑包路径没有改变,只有版本查询字符串。