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 ;)

Autore:


blog comments powered by Disqus

 

Calendar

<<  October 2017  >>
MonTueWedThuFriSatSun
2526272829301
2345678
9101112131415
16171819202122
23242526272829
303112345

View posts in large calendar