Seleziona una pagina

In questo articolo vedremo come realizzare un Custom Middleware per la minificazione del codice HTML.

HTMLMinifierAfter

Nel precedente articolo ASP.NET Core custom Middleware Ivano ha spiegato come implementare un Custom Middleware in ASP.NET Core, ora metteremo in pratica quanto visto in precedenza e creeremo un nostro nuovo Custom Middleware.

Come prima cosa creiamo la nostra nuova classe che identifica il nostro middleware:

    public class HtmlMinifierMiddleware
    {
        private readonly RequestDelegate _next;

        public HtmlMinifierMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public async Task Invoke(HttpContext context)
        {
                await _next(context);
        }
    }

         

A questo punto, il nostro scopo è di minimizzare l’HTML della nostra Response quindi il nostro middleware agirà dopo l’esecuzione del middleware precedente.

Prima di eseguire il middleware successivo è necessario avere il riferimento allo stream della nostra Response (altrimenti questa risulterà chiusa dopo l’esecuzione del middleware precedente), tramite questo stream potremo leggere il contenuto del Body della Response dopo l’esecuzione del middleware precedente.

Una volta recuperato il contenuto HTML della response potremo eseguire la regular expression che ci permette di eliminare gli spazi vuoto che sono presenti tra un tag e l’altro.

Di seguito il codice commentato:

    public class HtmlMinifierMiddleware
    {
        private readonly RequestDelegate _next;

        public HtmlMinifierMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public async Task Invoke(HttpContext context)
        {
            //Original Response
            var originalResponse = context.Response.Body;
            //Reference to body stream
            using (var stream = new MemoryStream())
            {
                context.Response.Body = stream;

                //Execute Next Middleware
                await _next(context);

                //Reset stream to starting point
                stream.Seek(0, SeekOrigin.Begin);

                using (var reader = new StreamReader(stream))
                {
                    //Current HTML Body
                    string responseBody = await reader.ReadToEndAsync();
                    //IF Response OK (200) and Content text/HTML
                    if (context.Response.StatusCode == 200 && context.Response.ContentType.ToLower().Contains("text/html"))
                    {
                        //Regular expression to remove white space between tags
                        responseBody = Regex.Replace(responseBody, @">\s+<", "><", RegexOptions.Compiled);
                        
                        //Prepare new stream for new response body
                        using (var memoryStream = new MemoryStream())
                        {
                            var bytes = Encoding.UTF8.GetBytes(responseBody);
                            memoryStream.Write(bytes, 0, bytes.Length);
                            memoryStream.Seek(0, SeekOrigin.Begin);
                            
                            //Copy new stream to original stream
                            await memoryStream.CopyToAsync(originalResponse, bytes.Length);

                        }
                    }
                }
            }
        }
    }

Ora non ci rimane che creare la Classe UseHtmlMinifier utile per la registrazione del nostro Middleware nella classe startup del progetto:

    public static class BuilderExtensions
    {
        public static IApplicationBuilder UseHtmlMinifier(this IApplicationBuilder app)
        {
            return app.UseMiddleware<HtmlMinifierMiddleware>();
        }
    }

Una volta terminato possiamo registrare il nostro Middleware nella classe startup:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(Configuration.GetSection("Logging")); loggerFactory.AddDebug(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseBrowserLink(); } else { app.UseExceptionHandler("/Home/Error"); } app.UseStaticFiles(); app.UseHtmlMinifier();

app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); }

Una volta terminato il tutto possiamo eseguire un test e vedere il risultato:

Prima Dopo
HTMLMinifierBefore HTMLMinifierAfter

Tutto qui!!!

Happy Coding 😉

Altri Articoli

ASP.NET Core SignalR: Differenze con la versione p...
views 375
La nuova versione di ASP.NET Core SignalR non è compatibile sia per la parte Server che per la parte Client alla versione precedente ASP.NET SignalR. ...
Novità ASP.NET Core 2 (Preview 2)
views 245
Lo scorso 28 giugno è stata rilasciata la Preview 2 di ASP.NET Core 2. Le principali novità della nuova versione ASP.NET Core sono: Razor Pages...
ASP.NET Core MVC Image TagHelper
views 149
In questo post conosceremo l’Image TagHelper, questo TagHelper si occupa di inserire un immagine all’interno della pagina. L’image TagHelper mette ...
ASP.NET Core MVC Cache TagHelper
views 127
In questo post conosceremo il Cache TagHelper, questo TagHelper si occupa di inserire del codice nella cache (MemoryCache) per un periodo di tempo. ...

Sono uno sviluppatore specializzato nella realizzazione di applicazioni web ASP.NET. Mi ritengo una persona fortunata perchè il mio lavoro coincide con la mia passione: Sviluppare codice!!! Ho incominciato a sviluppare codice dall’età di circa dieci anni con il famigerato Commodore 64. La mia svolta epocale è stato l’avvento di internet e dal 1995 ho cominciato a sviluppare siti web prima statici e poi dinamici (ASP) per poi approdare alla piattaforma .NET, da allora… non mi sono piu’ fermato!