Created
February 5, 2021 08:46
-
-
Save RichardD2/00b1a4f1c1d3e55dc565a7d764d79bfe to your computer and use it in GitHub Desktop.
UrlHelper extension to append a timestamp to a CSS / JS URL
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.IO; | |
using System.Linq; | |
using System.Web; | |
using System.Web.Caching; | |
using System.Web.Hosting; | |
using System.Web.Mvc; | |
namespace NBS.Core.Web.Mvc | |
{ | |
public static class UrlHelperExtensions | |
{ | |
private const string CachePrefix = "NBS:Fingerprint:"; | |
public static string AppendTimestamp(this UrlHelper url, string rootRelativePath) | |
{ | |
if (url is null) throw new ArgumentNullException(nameof(url)); | |
if (string.IsNullOrWhiteSpace(rootRelativePath)) return string.Empty; | |
string cacheKey = CachePrefix + rootRelativePath; | |
if (!(HttpRuntime.Cache[cacheKey] is string result)) | |
{ | |
string virtualPath = url.Content(rootRelativePath); | |
string minPath = url.RequestContext.HttpContext.IsDebuggingEnabled ? null : GetMinPath(virtualPath); | |
result = AppendTimestampCore(minPath, out var absolutePath) | |
?? AppendTimestampCore(virtualPath, out absolutePath) | |
?? virtualPath; | |
if (absolutePath != null) | |
{ | |
HttpRuntime.Cache.Insert(cacheKey, result, new CacheDependency(absolutePath)); | |
} | |
} | |
return result; | |
} | |
private static string GetMinPath(string virtualPath) | |
{ | |
int extensionIndex = virtualPath.LastIndexOf('.'); | |
if (extensionIndex == -1) return null; | |
if (4 < extensionIndex | |
&& virtualPath[extensionIndex - 4] == '.' | |
&& virtualPath[extensionIndex - 3].IsOneOf('M', 'm') | |
&& virtualPath[extensionIndex - 2].IsOneOf('I', 'i') | |
&& virtualPath[extensionIndex - 1].IsOneOf('N', 'n')) | |
{ | |
return null; | |
} | |
return virtualPath.Insert(extensionIndex, ".min"); | |
} | |
private static bool IsOneOf(this char c, [NotNull] params char[] values) => values.Any(v => v == c); | |
private static string AppendTimestampCore(string virtualPath, out string absolutePath) | |
{ | |
if (string.IsNullOrWhiteSpace(virtualPath)) | |
{ | |
absolutePath = null; | |
return null; | |
} | |
absolutePath = HostingEnvironment.MapPath(virtualPath); | |
if (string.IsNullOrWhiteSpace(absolutePath)) return null; | |
string sep = virtualPath.IndexOf('?') == -1 ? "?v=" : "&v="; | |
DateTime lastWriteTime = File.GetLastAccessTimeUtc(absolutePath); | |
return virtualPath + sep + lastWriteTime.Ticks.ToString("x"); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment