El lanzamiento de .NET 8 por parte de Microsoft en noviembre trajo todo tipo de excelentes características nuevas. Una de las mejoras interesantes introducidas en ASP.NET Core 8 es IExceptionHandler, una interfaz que facilita el manejo elegante de excepciones en aplicaciones web ASP.NET Core.
El manejo de errores tiene una larga historia en marcos y lenguajes de programación. IExceptionHandler simplifica el manejo de errores al proporcionar una devolución de llamada y una ubicación central para manejar excepciones conocidas. En este artículo, analizaremos cómo puede utilizar IExceptionHandler en sus aplicaciones ASP.NET Core 8 y presentaremos respuestas de error significativas al usuario.
Para utilizar los ejemplos de código proporcionados en este artículo, debe tener Visual Studio 2022 instalado en su sistema. Si aún no tienes una copia, puedes descargue Visual Studio 2022 aquí.
Cree un proyecto de API web ASP.NET Core en Visual Studio 2022
Para crear un proyecto de API web ASP.NET Core 8 en Visual Studio 2022, siga los pasos que se describen a continuación.
- Inicie el IDE de Visual Studio 2022.
- Haga clic en «Crear nuevo proyecto».
- En la ventana «Crear nuevo proyecto», seleccione «ASP.NET Core Web API» de la lista de plantillas que se muestran.
- Haga clic en Siguiente.
- En la ventana «Configura tu nuevo proyecto», especifica el nombre y la ubicación del nuevo proyecto.
- Opcionalmente, marque la casilla de verificación «Colocar solución y proyecto en el mismo directorio», según sus preferencias.
- Haga clic en Siguiente.
- En la ventana «Información adicional» que se muestra a continuación, seleccione «.NET 8.0 (soporte a largo plazo)» como versión del marco y asegúrese de que la casilla «Usar controladores» no esté marcada. Usaremos API mínimas en este proyecto.
- En otra parte de la ventana «Información adicional», deje el «Tipo de autenticación» configurado en «Ninguno» (el valor predeterminado) y asegúrese de que las casillas de verificación «Habilitar compatibilidad con Open API», «Configurar para HTTPS» y «Habilitar Docker» permanezcan sin marcar. . No utilizaremos ninguna de esas funciones aquí.
- Haga clic en Crear.
Usaremos este proyecto ASP.NET Core Web API para trabajar con la interfaz IExceptionHandler en las secciones siguientes.
¿Por qué necesitamos un controlador de excepciones?
En ASP.NET Core, un controlador de excepciones es un componente que puede manejar excepciones globalmente en una aplicación. Puede detectar todas las excepciones no controladas y luego generar respuestas de error apropiadas.
Un controlador de excepciones puede ayudar a implementar un mecanismo centralizado de manejo de errores, permitiendo que sus aplicaciones fallen sin problemas. Esto le permitirá garantizar que se manejen todas las excepciones, que los errores se registren y procesen correctamente y que se generen y presenten al usuario respuestas de error significativas.
Entendamos esto con un ejemplo. Considere el siguiente código.
using Microsoft.AspNetCore.Diagnostics; using Microsoft.AspNetCore.Mvc; using System.ComponentModel.DataAnnotations; using System.Net; var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.UseExceptionHandler(opt => { }); app.MapGet("/GenerateError", () => { throw new NotImplementedException(); }); app.Run();
Cuando ejecuta la aplicación y presiona el punto final /GenerateError, la respuesta que se muestra en su navegador web aparecerá como se muestra a continuación.
Tenga en cuenta que la respuesta de error no está formateada y es bastante difícil leer y comprender los metadatos de error de esta respuesta.
Presentamos la interfaz IExceptionHandler
El manejo de excepciones se ha utilizado en lenguajes de programación durante décadas para manejar errores de tiempo de ejecución en aplicaciones. ASP.NET Core 8 mejora significativamente el manejo de excepciones con la introducción de la interfaz IExceptionHandler. Puede crear una clase central para el manejo de excepciones en ASP.NET Core 8 implementando la interfaz IExceptionHandler.
La interfaz IExceptionHandler tiene este aspecto:
public interface IExceptionHandler { ValueTask<bool> TryHandleAsync(HttpContext httpContext, Exception exception, CancellationToken cancellationToken); }
La interfaz IExceptionHandler contiene la declaración del método TryHandleAsync. Este método acepta tres parámetros: una instancia de tipo HttpContext, una excepción y un CancellationToken. Devuelve ValueTask
Cuando implementa el método TryHandleAsync en su clase que extiende la interfaz IExceptionHandler, debe devolver un valor booleano de este método. Debe devolver verdadero si se manejó la excepción o falso en caso contrario.
Cree un controlador de excepciones personalizado en ASP.NET Core
Para implementar la interfaz IExceptionHandler, cree una nueva clase denominada GlobalExceptionHandler en un archivo del mismo nombre con una extensión .cs. E ingrese el siguiente código allí.
public class GlobalExceptionHandler(IHostEnvironment hostEnvironment, ILogger<GlobalExceptionHandler> logger) : IExceptionHandler { public async ValueTask<bool> TryHandleAsync(HttpContext httpContext, Exception exception, CancellationToken cancellationToken) { return true; } }
Su lógica de manejo de errores personalizada debe residir en el método TryHandleAsync. El siguiente fragmento de código muestra cómo puede manejar las excepciones que ocurren en su aplicación de forma asincrónica.
private const string ExceptionMessage = "An unhandled exception has occurred while executing the request.";
ValueTask asíncrono público
{
logger.LogError (excepción, la excepción es ¿Excepción? excepción.Mensaje: Mensaje de excepción);
var problemDetails = CreateProblemDetails(httpContext, excepción);
espere httpContext.Response.WriteAsJsonAsync (problemDetails, cancelationToken);
devolver verdadero;
}
Ahora aprovecharemos el código abierto. Middleware de detalles del problema para generar mensajes de error consistentes, estructurados y legibles por máquina. El método CreateProblemDetails devuelve una instancia de ProblemDetails que contiene los metadatos del error, como se muestra en el fragmento de código que se proporciona a continuación.
private ProblemDetails CreateProblemDetails(in HttpContext httpContext, in Exception exception)
{
httpContext.Response.ContentType = «aplicación/json»;
interruptor (excepción)
{
caso NotImplementedException notImplementedException:
httpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
romper;
por defecto:
httpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
romper;
}
devolver nuevos detalles del problema
{
Estado = (int)httpContext.Response.StatusCode,
Tipo = excepción.GetType().Nombre,
Título = «Ocurrió un error inesperado»,
Detalle = excepción.Mensaje,
Instancia = $»{httpContext.Request.Method} {httpContext.Request.Path}»
};
}
Código fuente completo de nuestro controlador de excepciones personalizado
La siguiente lista de código comprende el código fuente completo de la clase GlobalExceptionHandler.
public class GlobalExceptionHandler(IHostEnvironment hostEnvironment, ILogger<GlobalExceptionHandler> logger)
: IExceptionHandler
{
private const string ExceptionMessage = «Se ha producido una excepción no controlada al ejecutar la solicitud.»;
ValueTask asíncrono público
{
logger.LogError (excepción, la excepción es ¿Excepción? excepción.Mensaje: Mensaje de excepción);
var problemDetails = CreateProblemDetails(httpContext, excepción);
espere httpContext.Response.WriteAsJsonAsync (problemDetails, cancelationToken);
devolver verdadero;
}
ProblemDetails privados CreateProblemDetails (en HttpContext httpContext, en excepción Excepción)
{
httpContext.Response.ContentType = «aplicación/json»;
interruptor (excepción)
{
caso NotImplementedException notImplementedException:
httpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
romper;
por defecto:
httpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
romper;
}
devolver nuevos detalles del problema
{
Estado = (int)httpContext.Response.StatusCode,
Tipo = excepción.GetType().Nombre,
Título = «Ocurrió un error inesperado»,
Detalle = excepción.Mensaje,
Instancia = $»{httpContext.Request.Method} {httpContext.Request.Path}»
};
}
}
Registre el controlador de excepciones con la canalización de procesamiento de solicitudes
Ahora que nuestro controlador de excepciones personalizado está listo, debemos registrarlo en la canalización de procesamiento de solicitudes para comenzar a usarlo en nuestra aplicación. Puede registrar el controlador de excepciones incluyendo la siguiente línea de código en el archivo Program.cs.
builder.Services.AddExceptionHandler<GlobalExceptionHandler>();
Creemos ahora un punto final de manejo de errores en Program.cs. Cuando se invoca, este punto final mostrará una respuesta de error fácil de usar como se especifica en el controlador de errores configurado. Para crear un punto final de manejo de errores, ingrese el siguiente código en el archivo Program.cs.
app.MapGet("/GenerateError", () =>
{
lanzar nueva ValidationException();
});
La llamada al método UseExceptionHandler() configura la canalización de procesamiento de solicitudes en ASP.NET Core para manejar excepciones utilizando nuestro middleware.
app.UseExceptionHandler(opt => { });
Ahora, cuando ejecute la aplicación y presione el punto final /GenerateError, la respuesta que se muestra en el navegador web aparecerá como se muestra a continuación. ¡Mucho mejor!
Siempre es recomendable implementar su propio manejo de excepciones personalizado en su aplicación. Esto garantiza no sólo que la lógica de manejo de excepciones cumpla con sus requisitos, sino también que las respuestas de error se generen en el formato deseado. Naturalmente, implementar su propio controlador de excepciones también le brinda un control mucho más granular sobre el mecanismo de manejo de excepciones.
Copyright © 2024 IDG Communications, Inc.