Ahoj,
potřeboval jsem zajistit, aby odkazy na vlastní aplikační scriptz a css byly v release generovány s verzí (hash) jako do dělá tag helper asp-append-version=“true” v MVC. Jestli jsem něco nepřehlédl, tak DotVVM toto umí jen u EmbeddedResourceLocation ale u UrlResourceLocation to není.
Napsal jsem si vlastní třídu UrlFileVersionResourceLocation, kde jsem udělal logiku podobné té co mají v MVC LinkTagHelper.
Koukněte na to, zda by to nešlo dát přímo jako součást do DotVVM.
using System.Security.Cryptography;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.FileProviders;
using DotVVM.Framework.ResourceManagement;
public class UrlFileVersionResourceLocation : IResourceLocation
{
#region member varible and default property initialization
private static readonly char[] QueryStringAndFragmentTokens = new char[2] { '?', '#' };
public string Url { get; }
public string? DebugUrl { get; set; }
#endregion
#region constructors and destructors
public UrlFileVersionResourceLocation(string url, string? debugUrl = null)
{
this.Url = url;
this.DebugUrl = debugUrl;
}
#endregion
#region action methods
public string GetUrl(IDotvvmRequestContext context, string name)
{
var hostingEnvironment = context.Services.GetRequiredService<IWebHostEnvironment>();
var fileProvider = hostingEnvironment.WebRootFileProvider;
string url = context.TranslateVirtualPath(context.Configuration.Debug ? this.DebugUrl ?? this.Url : this.Url);
return context.Configuration.Debug ? url : AddFileVersionToPath(fileProvider, context.HttpContext.Request.PathBase, url);
}
#endregion
#region private member functions
private static string AddFileVersionToPath(IFileProvider fileProvider, IPathString requestPathBase, string path)
{
ArgumentNullException.ThrowIfNull(path);
string filePath = path;
int index = path.IndexOfAny(QueryStringAndFragmentTokens);
if (index != -1)
{
filePath = path[..index];
}
if (Uri.TryCreate(filePath, UriKind.Absolute, out var result) && !result.IsFile)
{
return path;
}
var fileInfo = fileProvider.GetFileInfo(filePath);
if (!fileInfo.Exists && requestPathBase.HasValue() && filePath.StartsWith(requestPathBase.Value!, StringComparison.OrdinalIgnoreCase))
{
string filePath2 = filePath[requestPathBase.Value!.Length..];
fileInfo = fileProvider.GetFileInfo(filePath2);
}
string value = !fileInfo.Exists ? path : QueryHelpers.AddQueryString(path, "v", GetHashForFile(fileInfo));
return value;
}
private static string GetHashForFile(IFileInfo fileInfo)
{
using (SHA256 sHA = SHA256.Create())
{
using (Stream inputStream = fileInfo.CreateReadStream())
{
return WebEncoders.Base64UrlEncode(sHA.ComputeHash(inputStream));
}
}
}
#endregion
}