ASP.NET MVC绑定缓存。(检测css文件更改)(内部行为)
我已经深入研究了ASP.NETMVC的内部功能(不同的原因),但仍然不能涵盖所有的行为。其中一个我没有的是subj 其工作方式如下: 如果我捆绑一些文件(例如css文件),框架会检测到这些更改并为新捆绑生成新id(以便于浏览器刷新更改),如href=“/Content/css?v=qartPE4jGe-l1u0i7kndzpzvzvtdh0kt8vbzza_uURjI1” 我真正想理解的是:ASP.NET MVC绑定缓存。(检测css文件更改)(内部行为),css,asp.net-mvc,bundle,Css,Asp.net Mvc,Bundle,我已经深入研究了ASP.NETMVC的内部功能(不同的原因),但仍然不能涵盖所有的行为。其中一个我没有的是subj 其工作方式如下: 如果我捆绑一些文件(例如css文件),框架会检测到这些更改并为新捆绑生成新id(以便于浏览器刷新更改),如href=“/Content/css?v=qartPE4jGe-l1u0i7kndzpzvzvtdh0kt8vbzza_uURjI1” 我真正想理解的是: 框架(可能不是MVC,而是.NET的东西)是如何检测到文件被更改的(因为没有活动的目录监视程序(即使we
非常感谢!ASP.NET优化框架将捆绑包响应缓存在
HttpContext.Cache
中,并使用a监视捆绑包中的每个文件的更改。这就是为什么更新文件会直接使缓存无效并重新生成捆绑包的原因
bundle文件名是bundle内容的散列,可确保在修改任何bundle文件时URL发生更改。bundle的虚拟路径用作缓存密钥
库中的相关代码(注意这有点过时,但我相信逻辑仍然是一样的):
内部BundleResponse GetBundleResponse(BundleContext)
{
//检查捆绑包响应是否在缓存中
BundleResponse BundleResponse=Bundle.CacheLookup(上下文);
if(bundleResponse==null | | context.enableTemtrumentation)
{
//如果没有,则生成bundle响应并缓存它
BundlerResponse=this.GenerateBundlerResponse(上下文);
if(context.UseServerCache)
{
this.UpdateCache(上下文,bundleResponse);
}
}
返回捆绑响应;
}
私有void UpdateCache(BundleContext,BundleResponse响应)
{
if(context.UseServerCache)
{
//创建捆绑包中所有文件路径的列表
列表=新列表();
list.AddRange(
在response.Files中从f开始
选择f.FullName);
list.AddRange(context.cacheDependencyDirectory);
字符串cacheKey=Bundle.GetCacheKey(context.BundleVirtualPath);
//将响应插入到具有监视的缓存依赖项的缓存中
//绑定文件以进行更改
Insert(cacheKey,response,newcachedependency(list.ToArray());
context.HttpContext.Response.AddCacheItemDependency(cacheKey);
此._cacheKey.Add(cacheKey);
}
}
最后,对于可用的旧捆绑URL,我认为您会发现它们要么从浏览器缓存返回,要么实际返回捆绑的最新版本,因为捆绑路径没有改变,只有版本查询字符串。本网站提供了一些关于捆绑机制的见解:至于您的第二个问题,似乎是由defaul提出的t、 使用服务器缓存。捆绑ID是文件内容的散列,因此在更改内容时会更改。旧版本不存储在服务器上,不再可用。URL很可能仍然有效(因为它只是一个查询字符串,用于使浏览器意识到需要下载新内容)但是你会得到新的内容,而不是旧的内容。谢谢你的回答。但是,我不确定我看到了问题的两部分中任何一部分的确切答案。1.它如何准确地检测相关文件的更改?2.缓存实际存储值的位置(或方式)(如果存在多个包(旧包和新包))。我已更新了答案,但简而言之,
CacheDependency
对象监视文件的更改,并使用捆绑虚拟路径作为键缓存捆绑响应(每个捆绑仅存储一个条目,因此更新捆绑文件将删除现有条目).是的,但核心问题是它如何准确地监控文件的更改?是否存在任何系统监视程序(我对此表示怀疑,因为当应用程序未运行且文件已更改时,情况如何)?否则,它是如何检查文件修改的?在每个请求上?好吧,谢谢你的回答,但对我来说它听起来仍然像是:“它只是使用缓存”。好吧,我确信它使用缓存(这是web(和许多其他)技术的工作方式),但我的问题是实际的(不仅仅是一些理论上的,捆绑使用的是哪些类或模块):这是为了了解页面呈现是否会检查每个web请求的文件更改(来自捆绑),如果不是,那么(奇怪地/理论上)它以何种方式监控这些更改?我已经提供了您所问问题的答案。如果您想了解CacheDependency
的内部结构以及它监控文件的具体方式,那么我建议您发布一个不同的问题。我建议您在得出“它只是使用缓存”的结论之前仔细阅读我的答案.
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);
}
}