获取缓存破坏版本字符串的服务/扩展程序

时间:2017-11-21 10:51:39

标签: c# asp.net-core asp.net-core-mvc asp.net-core-2.0 offline-caching

背景

我有一个应用程序,其中3个视图使用html5离线应用程序功能。因此,我在剃刀视图中生成了一个应用程序清单。此视图的简化版本可能如下所示:

CACHE MANIFEST

CACHE:
/site.min.css
/site.min.js

为了使离线应用程序正常运行,缓存的文件必须与应用程序中的脱机页面请求的文件完全匹配。但是,我想将'cache-busting'版本字符串应用于此清单中引用的js / css资源。对于HTML标记,ScriptTagHelper支持这一点,但我没有找到任何支持纯URL的帮助/扩展方法(如上面清单所示)。

参考this post,我已经通过在我的清单视图中注入FileVersionProvider并使用AddFileVersionToPath()方法解决了这个问题,如下所示:

@inject FileVersionProvider versionProvider
CACHE MANIFEST

CACHE:
@versionProvider.AddFileVersionToPath("/site.min.css")
@versionProvider.AddFileVersionToPath("/site.min.js")

但是,FileVersionProvider类位于Microsoft.AspNetCore.Mvc.TagHelpers.Internal命名空间中,从维护角度来看,这并不能让我满怀信心。

最后,我为此设置的DI设置并不完全理想(见下文)。我不喜欢我需要拨打GetService()的电话,我当然应该指定一个特定的MemoryCache

services.AddSingleton<FileVersionProvider>(s => 
    new FileVersionProvider(
        s.GetService<IHostingEnvironment>()?.WebRootFileProvider, 
        s.GetService<IMemoryCache>(), 
        new PathString("") ));

问题

有没有人要求之前使用版本字符串创建指向js / css资源的链接?如果是这样,是否有更优雅的解决方案?

1 个答案:

答案 0 :(得分:1)

您尝试过this extension method吗?它在ASP.NET Core 2.1 LTS上为我工作,而没有任何依赖注入,只是扩展方法。如果您仍然使用它,也应该在2.0中工作。

我有一个类似的用例,其中SCEditor从JavaScript传递的路径加载CSS。

@{
    // Without version hash cache buster, the editor internally cache the request and we don't get the new stylesheet - even not with CTRL + F5
    string editorThemePath = this.AddFileVersionToPath("/css/my-editor-theme.css");
}
<script>
      sceditor.create(editorTextarea, {
            // ...
            style: '@editorThemePath'
      })
</script>

生成的HTML

<script>
      sceditor.create(editorTextarea, {
            style: '/css/my-editor-theme.css?v=sRU_qBg7xyQElPLskjekOlvSHdRF2Ap1leTP8ui4CaI',
      })
</script>

请记住,此实现需要相对于wwwroot的路径。因此,在这种情况下,/css/my-editor-theme.csswwwroot/css/my-editor-theme.css中。

如果将FileVersionProvider的第一个参数从hostingEnvironment.WebRootFileProvider替换为hostingEnvironment.ContentRootFileProvider,则可以更改。但是我尚未测试此操作的副作用和安全性问题,因此,如果可能的话,您应该留在wwwroot上,因为此文件夹设计为可公共访问的。