16

我一直在深入研究 ASP.NET MVC 内部功能(不同的原因),但仍然无法涵盖所有​​行为。我没有的其中之一是主题。

它的工作方式如下:

如果我捆绑了一些文件(例如 css 文件),框架会检测到这些更改并为新捆绑包生成新 id(以使浏览器更容易刷新更改),例如 href="/Content/css?v=qartPE4jGe- l1U0I7kNDZPZzVTdh0kT8VBZZA_uURjI1"。

我实际上想了解的是:

  1. 框架(可能不是 MVC 而是 .NET 的东西)究竟如何检测到文件已更改(因为没有活动的目录观察程序(因为即使网络服务器脱机,我也可以更改文件)以查看文件更改live,并且系统实际上检测到文件内容的更改(我只是尝试重新保存文件而不更改其内容并且捆绑包编号也没有更改))?(我认为显然系统无法比较每个文件内容来检测每个请求的变化)。

  2. 框架在哪里(以及如何)存储当前包 ID以及它如何存储以前的版本(因为以前的包在转到它们的 url 时仍然可用)?

非常感谢!

4

1 回答 1

14

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 工作,我想您会发现它们要么从浏览器缓存返回,要么实际上返回捆绑的最新版本,因为捆绑路径不会改变,只有版本查询字符串。

于 2014-01-23T17:14:09.993 回答