¿Hay una manera de crear un método de extensión HTML para crear una ruta de archivo estática de búsqueda de caché?

Estoy usando .netcore 3.1 y c# para mi proyecto.

He creado una clase de Ayudante que genera un hash de un archivo y lo añade al final de la ruta del archivo en la vista.

Por ejemplo: Envíe el camino "/global.js", y luego consiga ese archivo para apresurarlo. Luego regresa el camino como "/global.js?v={hash}".

Esto se hace enviando los siguientes objetos al Controlador de Bases e inicializando la clase de ayudantes y estableciendo como ViewBag para ser utilizado dentro del _Layout.cshtml:

  • IDistribuido Cache caché
  • ActionContext actionContext

Clase de ayuda:

public CacheContentTagHelper(IDistributedCache cache, ActionContext actionContext, string contentRootPath)
    {
        this.contentRootPath = contentRootPath;
        this.cache = cache;

        // use the IFileProvider configured for the Static Files middleware
        this.fileProvider = new PhysicalFileProvider(contentRootPath);
        this.urlHelper = new UrlHelper(actionContext);
    }

    public string GetUrl(string filePath)
    {
        string path = filePath;

        if (!string.IsNullOrEmpty(path))
        {
            IFileInfo file = fileProvider.GetFileInfo(urlHelper.Content($"~/wwwroot{path}"));

            if (file?.Exists == true && !file.IsDirectory && !string.IsNullOrWhiteSpace(file.PhysicalPath))
            {
                string hash = Task.Run(() => GetFileHashAsync(file)).Result;
                path = !string.IsNullOrWhiteSpace(hash)
                    ? $"{path}?v={hash}"
                    : path;
            }
        }

        return path;
    }

Y luego hago lo siguiente a la vista para ejecutar ese método:

@{ 
    CacheContentTagHelper test = (CacheContentTagHelper)ViewBag.CacheContentTagHelper;

}

Pero, me gustaría poder hacer .script("@this.GetUrl("/resources/js/global.min.js")").wait(function () {.

Cualquier ayuda sería apreciada.

Pregunta hecha hace 3 años, 4 meses, 28 días - Por quantumcoder403a


2 Respuestas:

  • Sí, puedes crear un método de extensión HTML para lograr lo que deseas. Aquí tienes un ejemplo de cómo hacerlo:

    • Crea una clase estática que contenga el método de extensión HTML:
    csharp
    public static class CacheContentTagHelperExtensions
    {
        public static string GetUrl(this IHtmlHelper htmlHelper, string filePath)
        {
            var cacheContentTagHelper = htmlHelper.ViewData["CacheContentTagHelper"] as CacheContentTagHelper;
    
            if (cacheContentTagHelper != null)
            {
                return cacheContentTagHelper.GetUrl(filePath);
            }
    
            return filePath;
        }
    }
    
    • Para utilizar este método de extensión en tus vistas, primero asegúrate de importar el espacio de nombres donde se encuentra la clase estática:
    csharp
    @using TuNamespace.CacheContentTagHelperExtensions
    
    • Luego, puedes llamar al método de extensión en tu vista de la siguiente manera:
    csharp
    
    

    Con esto, puedes invocar el método de extensión directamente en tu vista, simplificando el código y logrando el resultado deseado. ¡Espero que esta solución te sea útil! Si tienes alguna otra pregunta o necesitas más ayuda, no dudes en decírmelo.

    Respondida el Dec 18, 2020 a las 16:59 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • Para crear un método de extensión HTML para generar una ruta de archivo estática con control de caché, puedes seguir estos pasos:

    • Crea una clase auxiliar: Crea una clase auxiliar que contenga el método de extensión que necesitas. Esta clase debe tener una referencia a la caché distribuida y al contexto de acción.
    • Define el método de extensión: En la clase auxiliar, define un método de extensión para la clase `HtmlHelper`. Este método debe aceptar una ruta de archivo y devolver la ruta de archivo con el hash de control de caché añadido.
    • Registra el método de extensión: En el archivo `Startup.cs` de tu aplicación, registra el método de extensión utilizando el método de extensión `AddRazorRuntimeCompilation`. Esto hará que el método de extensión esté disponible en todas las vistas.

    Aquí hay un ejemplo de cómo podrías implementar estos pasos:

    Clase auxiliar:

    csharp
    public static class CacheContentExtensions
    {
        public static string GetCacheBustingUrl(this IHtmlHelper htmlHelper, string filePath)
        {
            // Obtener la caché distribuida y el contexto de acción
            var cache = htmlHelper.ViewContext.HttpContext.RequestServices.GetService();
            var actionContext = htmlHelper.ViewContext.ActionContext;
    
            // Obtener el hash del archivo
            string hash = await GetFileHashAsync(filePath, cache);
    
            // Devolver la ruta del archivo con el hash
            return $"{filePath}?v={hash}";
        }
    
        private static async Task GetFileHashAsync(string filePath, IDistributedCache cache)
        {
            // Obtener el archivo del proveedor de archivos
            var fileProvider = new PhysicalFileProvider(hostingEnvironment.ContentRootPath);
            var file = fileProvider.GetFileInfo(filePath);
    
            // Comprobar si el archivo existe
            if (file == null || !file.Exists)
            {
                return null;
            }
    
            // Obtener el hash del archivo de la caché
            var cacheKey = $"CacheBustingHash:{filePath}";
            var cachedHash = await cache.GetStringAsync(cacheKey);
    
            // Si el hash no está en caché, calcularlo y guardarlo en caché
            if (cachedHash == null)
            {
                using (var stream = file.CreateReadStream())
                {
                    var hash = await MD5.Create().ComputeHashAsync(stream);
                    cachedHash = Convert.ToBase64String(hash);
                    await cache.SetStringAsync(cacheKey, cachedHash, new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(30) });
                }
            }
    
            // Devolver el hash
            return cachedHash;
        }
    }
    

    Registro del método de extensión:

    csharp
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddRazorRuntimeCompilation();
    }
    

    Uso del método de extensión en la vista:

    cshtml
    @Html.GetCacheBustingUrl("/resources/js/global.min.js")
    

    Este método de extensión generará una ruta de archivo estática con un hash de control de caché añadido, que se puede utilizar para evitar problemas de almacenamiento en caché del navegador.

    Respondida el Dec 18, 2020 a las 17:07 - por Gemini

    Votos positivos: 0 | Votos negativos: 0