javascript版本(asp-append-version)如何在ASP.NET Core MVC中工作

Ily*_*dik 41 c# asp.net-core-mvc asp.net-core

似乎新的MVC(链接)中不支持动态捆绑,应该使用gulp任务来完成.MVC支持一些名为的新属性asp-append-version,但我没有找到任何关于它是如何工作的解释.我怀疑它正在计算文件内容的一些哈希值,甚至在文件更改后更新它.有没有关于它是如何工作的文件?

我也想知道它是如何检测文件更改或者它是否只是在每次MVC分析剃刀标记时重新计算哈希值.

Dan*_*.G. 80

您可以检查LinkTagHelper源代码,您将看到它基本上是通过以下方式将版本查询字符串添加到href值FileVersionProvider:

if (AppendVersion == true)
{
    EnsureFileVersionProvider();

    if (Href != null)
    {
        output.Attributes[HrefAttributeName].Value = _fileVersionProvider.AddFileVersionToPath(Href);
    }
}

private void EnsureFileVersionProvider()
{
    if (_fileVersionProvider == null)
    {
        _fileVersionProvider = new FileVersionProvider(
                HostingEnvironment.WebRootFileProvider,
                Cache,
                ViewContext.HttpContext.Request.PathBase);
    }
}
Run Code Online (Sandbox Code Playgroud)

FileVersionProvider计算使用文件内容的哈希SHA256算法.然后它将对其进行url编码并将其添加到查询字符串中,如下所示:

path/to/file?v=B95ZXzHiOuQJzhBoHlSlNyN1_cOjJnz2DFsr-3ZyyJs
Run Code Online (Sandbox Code Playgroud)

只有在文件更改时才会重新计算哈希值,因为它会添加到缓存中,但具有基于文件监视器的到期触发器:

if (!_cache.TryGetValue(path, out value))
{
    value = QueryHelpers.AddQueryString(path, VersionKey, GetHashForFile(fileInfo));
    var cacheEntryOptions = new MemoryCacheEntryOptions().AddExpirationToken(_fileProvider.Watch(resolvedPath));
    _cache.Set(path, value, cacheEntryOptions);
}
Run Code Online (Sandbox Code Playgroud)

这个观察者由提供者HostingEnvironment.WebRootFileProvider实现IFileProvider:

//
// Summary:
//     Creates a change trigger with the specified filter.
//
// Parameters:
//   filter:
//     Filter string used to determine what files or folders to monitor. Example: **/*.cs,
//     *.*, subFolder/**/*.cshtml.
//
// Returns:
//     An Microsoft.Framework.Caching.IExpirationTrigger that is triggered when a file
//     matching filter is added, modified or deleted.
IExpirationTrigger Watch(string filter);
Run Code Online (Sandbox Code Playgroud)

注意:您可以通过检查以下值中的值来自己查看缓存的值IMemoryCache:

//give the link:
<link rel="stylesheet" asp-append-version="true" href="~/css/site.css" />

//You can check the cached version
this.Context.RequestServices.GetRequiredService<IMemoryCache>().Get("/css/site.css")

//Which will show a value like:
/css/site.css?v=B95ZXzHiOuQJzhBoHlSlNyN1_cOjJnz2DFsr-3ZyyJs
Run Code Online (Sandbox Code Playgroud)

  • @AxiomaticNexus 似乎没有任何钩子可以让您使用不同的“FileVersionProvider”,您可以使用“IHostingEnvironment.ContentRootFileProvider”创建它(即使“FileVersionProvider”依赖于“IFileProvider”,因此理论上它可以正常工作`ContentRootProvider`)。我猜标签助手的设计考虑了来自 wwwroot 的文件,也许它值得在 github 上达到 MS。 (3认同)
  • 看一下源代码,看来`asp-append-version`只适用于`WebRootFileProvider`.有没有办法让它可以使用`PhysicalFileProvider`服务的`wwwroot`目录之外的文件? (2认同)

JJS*_*JJS 14

在剃刀

var fileVersion = @Context.AddFileVersionToPath("./path/to/resource");
Run Code Online (Sandbox Code Playgroud)

扩展方法

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.Extensions.DependencyInjection;

public static class HttpContextExtensions
{
    public static string AddFileVersionToPath(this HttpContext context, string path)
    {
        return context
            .RequestServices
            .GetRequiredService<IFileVersionProvider>()
            .AddFileVersionToPath(context.Request.PathBase, path);
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 13

根据FileVersionProvider的当前实现,仅将哈希添加到相对文件路径,例如,<script src="~/js/jquery.min.js" asp-append-version="true"></script> 在使用绝对路径的情况下,例如https://code.jquery.com/jquery-3.1.1.js,不添加哈希.

  • 那么绝对路径的解决方案是什么? (4认同)