2015-10-26 4 views
18

Sembra che non vi sia alcun raggruppamento dinamico supportato nel nuovo MVC (link), e dovrebbe essere eseguito utilizzando un'attività di gulp. MVC supporta alcuni nuovi attributi chiamati asp-append-version, ma non ho trovato alcuna spiegazione su come funziona. Sospetto che stia calcolando un po 'di hash del contenuto del file e addirittura lo aggiorna dopo un cambio di file. C'è qualche documentazione su come funziona?Come funziona la versione javascript (asp-append-version) in ASP.NET Core MVC

Mi chiedo anche come rileva le modifiche al file o se si ricalcola l'hash solo ogni volta che MVC analizza il markup del rasoio.

risposta

39

È possibile controllare il codice LinkTagHelper fonte, dove potrete vedere è fondamentalmente l'aggiunta di una stringa di query di versione per il valore href tramite una 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); 
    } 
} 

Il FileVersionProvider sarà calcolare l'hash del contenuto dei file utilizzando l'algoritmo SHA256. Sarà quindi url codificarlo e aggiungerlo alla stringa di query come in:

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

L'hash viene ricalcolato solo quando il file cambia, in quanto viene aggiunto alla cache, ma con un trigger di scadenza sulla base di un file watcher:

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

questo watcher è fornito da HostingEnvironment.WebRootFileProvider, che implementa 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); 

Nota: È possibile visualizzare i valori memorizzati nella cache da soli controllando i valori nella 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 
+0

Grazie, che risponde a tutto! –

+1

Guardando il codice sorgente, sembra che 'asp-append-version' funzioni solo con' WebRootFileProvider'. C'è un modo per farlo funzionare con file al di fuori della directory 'wwwroot' servita da un' PhysicalFileProvider'? – AxiomaticNexus

+0

@AxiomaticNexus Non sembra esserci alcun gancio per utilizzare un diverso 'FileVersionProvider' che si creerebbe usando' IHostingEnvironment.ContentRootFileProvider' (anche se 'FileVersionProvider' dipende da' IFileProvider' quindi in teoria funzionerebbe bene con 'ContentRootProvider'). Immagino che il tag helper sia stato progettato con i file di wwwroot in mente, forse vale la pena raggiungere MS su github. –

2

Secondo l'attuale implementazione di FileVersionProvider, si aggiunge hash solo per il percorso del file relativo, per esempio <script src="~/js/jquery.min.js" asp-append-version="true"></script> Nel caso in cui venga utilizzato il percorso assoluto, ad es. https://code.jquery.com/jquery-3.1.1.js, l'hash non verrebbe aggiunto.

2

In Razor

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

metodo di estensione

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