Favicon y ¿por qué Configure() podría ejecutarse dos veces por petición en ASP.NET Core y cómo evitarlo?
Quizás te hayas encontrado con la situación siguiente que voy a comentar o quizás te hayas fijado, (o posiblemente no y en cualquier caso lo harás a partir de ahora) que a veces, puede ocurrir que cuando ponemos un punto de interrupción dentro de Configure() en nuestras aplicaciones ASP.NET Core y ejecutamos la app Web, observamos que los middlewares se ejecutan dos veces en cada petición.
Aunque hablaré sobre los middlewares de ASP.NET Core en otras entradas, valga un pequeño spoiler rápido de momento para indicar que cada petición (request) debería entrar y salir (response) una vez, aunque en determinadas circunstancias y si prestamos atención podemos encontrarnos con la situación concreta de que el proceso entra y sale dos veces.
Ahora bien, ¿porqué puede llegar a ocurrir esto?.
Pongamos el siguiente código de ejemplo:
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.Run(async context => { await context.Response.WriteAsync("Hello World!"); }); }
Si ponemos un punto de interrupción en la respuesta y ejecutamos nuestra aplicación Web, veremos que la petición entra dos veces.
Pero hay una explicación realmente.
Nuestra aplicación Web se ejecuta de forma correcta y esperada de acuerdo al comportamiento que debe tener según el código anterior, aunque a lo mejor no lo parezca.
El culpable de que esto suceda realmente es en parte del navegador Web, el cuál al no obtener favicon en la petición, realiza una segunda petición para obtenerlo, y en parte al código de nuestro ejemplo.
Si pulsamos F12 en Chrome y ejecutamos la petición, veremos algo parecido a lo siguiente:
Depurando con Visual Studio veremos que efectivamente, la petición entra en el middleware dos veces.
Si ejecutamos la petición Web con Postman (por ejemplo), observaremos en Visual Studio que la petición sólo ocurre una vez.
En realidad, Chrome pide a la aplicación Web el fichero favicon.ico, de ahí esa segunda petición. Postman sin embargo, no realiza esa petición, de ahí que sólo se ejecute una vez.
Ahora bien, ¿existe alguna forma de resolver esto?.
En mi caso, mi aplicación Web de ASP.NET Core tiene dentro del directorio wwwroot el fichero favicon.ico (que es dónde estará siempre por defecto, y en caso contrario deberíamos indicarlo).
El matiz del ejemplo que he expuesto es que estoy omitiendo el uso de ficheros estáticos.
Así que para evitar que Chrome realice dos peticiones debería escribir el siguiente código en mi aplicación ASP.NET Core:
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseStaticFiles(); app.Run(async context => { await context.Response.WriteAsync("Hello World!"); }); }
Aquí uso el middleware que nos ofrece ASP.NET Core para utilizar ficheros estáticos UseStaticFiles().
Este middleware permite que ASP.NET Core sirva de forma directa y dentro de wwwroot todos los archivos estáticos de la Web: imágenes, JavaScript, HTML y CSS.
Realizando esto, la petición sólo se cursará desde Chrome una sóla vez tal y como esperaríamos evitando que se procese código o procesos innecesarios internamente.
Puedes acceder a más información sobre los ficheros estáticos en ASP.NET Core en este enlace.
Happy Coding!