Enrutamiento y errores
Introducción
El enrutamiento es un tema muy importante en el desarrollo web. Las rutas son la base de la navegación en un sitio web y en Internet en general. Las rutas definen el camino que los usuarios finales pueden seguir para navegar por el sitio web. Estas rutas deben ser claras y precisas para representar lo mejor posible el contenido de la página.
El enrutamiento consiste simplemente en asociar una petición HTTP a un gestor de rutas. Este gestor procesará entonces la ruta según su implementación. Las rutas se definen cuando se inicia la aplicación y esta sección describe varias formas de configurar rutas. El enrutamiento también es responsable de generar enlaces para redirecciones, por ejemplo.
En este capítulo se aborda el problema del enrutamiento y se describen las distintas APIs encargadas de procesar las solicitudes HTTP y las rutas. El enrutamiento a través de ASP.NET Core permite implementar multitud de funciones que se explicarán en las siguientes secciones. Por último, el capítulo abordará la gestión de errores y páginas de excepción dentro de un proyecto ASP.NET Core.
Gestión de las URL
El proceso de determinación de una ruta es sencillo. En general, una aplicación web sólo tiene una colección de rutas. Para determinar qué ruta tomar en función de la petición, el sitio escaneará todas las rutas y, mediante un sistema de correspondencia, determinará la primera ruta capaz de responder a la petición.
Con ASP.NET Core, hay dos componentes importantes de gestión de rutas:
-
La interfaz IRouter, que determina si la petición corresponde a una de las rutas registradas en la aplicación.
-
RouteMiddleware, que inicia la llamada al proceso de determinación de la ruta. Si se encuentra una ruta, el proceso continúa hacia el componente responsable de procesar la petición, según la ruta específica. En caso contrario, el middleware continúa encadenando las llamadas al middleware.
En resumen, el middleware llama al método RouteAsync de IRouter sobre todas las rutas para determinar cuál es la más adecuada. La clase responsable de determinar si la petición coincide con una ruta es la clase TemplateMatcher a través del método TryMatch.
Como el método TryMatch es bastante complejo, esta sección no lo tratará en detalle, ya que no es el propósito de este capítulo. Sin embargo, merece la pena echar un vistazo rápido a la secuencia de operaciones...
Middleware y restricciones
Cada petición se procesa a través de un único middleware de enrutamiento llamado RouterMiddleware. Este redirige la petición a un handler que la procesa. Su código es muy sencillo:
public async Task Invoke(HttpContext httpContext)
{
var context = new RouteContext(httpContext);
context.RouteData.Routers.Add(_router);
await _router.RouteAsync(context);
if (context.Handler == null)
{
_logger.RequestDidNotMatchRoutes();
await _next.Invoke(httpContext);
}
else
{
httpContext.Features[typeof(IRoutingFeature)] = new
RoutingFeature()
{
RouteData = context.RouteData,
};
await context.Handler(context.HttpContext);
}
}
La primera parte del middleware permite la creación de un objeto de contexto RouteContext para la gestión de rutas. Es este objeto el que se modificará en el proceso de determinación de una ruta y el que contendrá el resto de operaciones (si se encuentra una ruta) a través de su propiedad RequestDelegate Handler.
var context = new RouteContext(httpContext);
context.RouteData.Routers.Add(_router);
El objeto de enrutamiento inyectado, simbolizado por la propiedad _router, es por defecto la clase Router, que implementa IRouter y se utiliza para determinar la ruta.
A continuación, el middleware simplemente llama al método RouteAsync()para encontrar la ruta correcta para la petición entrante. Para cada ruta registrada, el middleware comprobará que la plantilla se corresponde con la petición a través de la clase...
Páginas de error
Los errores y las excepciones son habituales en la programación informática y ASP.NET Core no es una excepción. El sistema nunca es inmune y el desarrollador debe disponer de todas las herramientas necesarias para gestionar las situaciones de error, de la forma más eficaz posible.
En primer lugar, el desarrollador puede configurar una página de excepción que se mostrará cuando se produzca un error en el sitio web. Esta página, diseñada específicamente para la depuración y para ser utilizada sólo durante la fase de desarrollo del sitio, muestra una serie de información útil para ayudar a localizar el problema. El siguiente código configura esta página en la clase Startup.
public void Configure(IApplicationBuilder app,
IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
Aquí hay dos cosas importantes:
-
La prueba para comprobar que el entorno del sistema está en desarrollo (se puede modificar en los parámetros del proyecto).
-
El método UseDeveloperExceptionPage para mostrar una página de excepción cuando se produce un error en el código.
Una vez más, esta página sólo se debe utilizar en modo de desarrollo, ya que es probable que muestre información sensible en el sitio.
Probar esta página es muy sencillo: basta con lanzar una excepción en cualquier parte del código:
throw new Exception("Exception triggered!");
Cuando el código lanza una excepción, el servidor redirige automáticamente a la página de error, proporcionando una serie de información de depuración.
Página de excepciones para los desarrolladores
La información contenida en esta página de excepción es:
-
La pila de ejecución: muestra la pila de ejecución del código que ha sido llamado, haciendo zoom en la línea que lanzó la excepción, el archivo que contiene el código, la línea, etc.
-
La petición: visualización de la petición que se ha enviado al servidor con los parámetros de la cadena...