diff --git a/src/DNTCommon.Web.Core/DNTCommon.Web.Core.csproj b/src/DNTCommon.Web.Core/DNTCommon.Web.Core.csproj index 0ab1fcb..2793f79 100644 --- a/src/DNTCommon.Web.Core/DNTCommon.Web.Core.csproj +++ b/src/DNTCommon.Web.Core/DNTCommon.Web.Core.csproj @@ -1,7 +1,7 @@ DNTCommon.Web.Core provides common scenarios' solutions for ASP.NET Core applications. - 4.8.0 + 4.9.0 Vahid Nasiri net8.0;net7.0;net6.0; true diff --git a/src/DNTCommon.Web.Core/Mvc/FileVersionHashProvider.cs b/src/DNTCommon.Web.Core/Mvc/FileVersionHashProvider.cs new file mode 100644 index 0000000..c5acf58 --- /dev/null +++ b/src/DNTCommon.Web.Core/Mvc/FileVersionHashProvider.cs @@ -0,0 +1,46 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc.ViewFeatures; +using Microsoft.AspNetCore.WebUtilities; +using Microsoft.Extensions.DependencyInjection; + +namespace DNTCommon.Web.Core; + +/// +/// This utility class will help you to add your `asp-append-version` like query string value to the .css or .js files. +/// +public static class FileVersionHashProvider +{ + private static readonly string ProcessExecutableModuleVersionId = + Assembly.GetEntryAssembly()!.ManifestModule.ModuleVersionId.ToString("N"); + + /// + /// Adds a version hash to a specified file. + /// If you can't use `asp-append-version` directlty in Blazor apps, use this method instead. + /// + /// Encapsulates all HTTP-specific information about an individual HTTP request + /// The path of the .js or .css file to which version should be added + /// + /// If it's not possible to calculate the hash of the filePath, this value will be used. + /// If you don't specify it, Assembly.GetEntryAssembly()!.ManifestModule.ModuleVersionId will be used for it. + /// + /// + public static string GetFileVersionedPath(this HttpContext httpContext, string filePath, string? defaultHash = null) + { + ArgumentNullException.ThrowIfNull(httpContext); + + var fileVersionedPath = httpContext.RequestServices.GetRequiredService() + .AddFileVersionToPath(httpContext.Request.PathBase, filePath); + + return IsEmbeddedOrNotFound(fileVersionedPath, filePath) + ? QueryHelpers.AddQueryString(filePath, new Dictionary(StringComparer.Ordinal) + { + { + "v", defaultHash ?? ProcessExecutableModuleVersionId + } + }) + : fileVersionedPath; + } + + private static bool IsEmbeddedOrNotFound(string fileVersionedPath, string filePath) + => string.Equals(fileVersionedPath, filePath, StringComparison.Ordinal); +} \ No newline at end of file