web-dev-qa-db-fra.com

Comment fonctionne la version javascript (asp-append-version) dans ASP.NET Core MVC

Il semble qu'il n'y ait pas de regroupement dynamique pris en charge dans le nouveau MVC ( link ), et cela devrait être fait en utilisant une tâche gulp. MVC prend en charge un nouvel attribut appelé asp-append-version, mais je n'ai trouvé aucune explication sur son fonctionnement. Je soupçonne qu'il calcule du hachage du contenu du fichier et le met même à jour après un changement de fichier. Existe-t-il une documentation sur son fonctionnement?

Je me demande également comment il détecte les modifications du fichier ou s'il recalcule simplement le hachage à chaque fois que le MVC analyse le balisage du rasoir.

37
Ilya Chernomordik

Vous pouvez vérifier le code source LinkTagHelper , où vous verrez qu'il ajoute essentiellement une chaîne de requête de version à la valeur href via un 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);
    }
}

Le FileVersionProvider calculera le hachage du contenu du fichier en utilisant le SHA256 algorithme . Il l'aura ensuite encodé et ajouté à la chaîne de requête comme dans:

path/to/file?v=B95ZXzHiOuQJzhBoHlSlNyN1_cOjJnz2DFsr-3ZyyJs

Le hachage sera recalculé uniquement lorsque le fichier change , car il est ajouté au cache mais avec un déclencheur d'expiration basé sur un observateur de fichier:

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);
}

Cet observateur est fourni par HostingEnvironment.WebRootFileProvider, qui implémente 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);

Remarque: Vous pouvez voir les valeurs mises en cache vous-même en inspectant les valeurs dans 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
73
Daniel J.G.

ASP.NET Core 2.2 et versions ultérieures

Dans Razor

var fileVersion = @Context.AddFileVersionToPath("./path/to/resource");

Méthode d'extension

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);
    }
}

ASP.NET Core 2.1 et versions antérieures

Dans Razor

var fileversion = '@this.AddFileVersionToPath("/js/components/forms.js")';

Méthode d'extension

using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Razor;
using Microsoft.AspNetCore.Mvc.TagHelpers.Internal;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;

public static class IRazorPageExtensions
{
    public static string AddFileVersionToPath(this IRazorPage page, string path)
    {
        var context = page.ViewContext.HttpContext;
        IMemoryCache cache = context.RequestServices.GetRequiredService<IMemoryCache>();
        var hostingEnvironment = context.RequestServices.GetRequiredService<IHostingEnvironment>();
        var versionProvider = new FileVersionProvider(hostingEnvironment.WebRootFileProvider, cache, context.Request.Path);
        return versionProvider.AddFileVersionToPath(path);
    }
}
13
JJS

Selon l'implémentation actuelle de FileVersionProvider , le hachage n'est ajouté qu'au chemin de fichier relatif, par ex. <script src="~/js/jquery.min.js" asp-append-version="true"></script> Dans le cas où un chemin absolu est utilisé, par ex. https://code.jquery.com/jquery-3.1.1.js, le hachage ne serait pas ajouté.

13