DiezX.Api.Commons
1.12.0
dotnet add package DiezX.Api.Commons --version 1.12.0
NuGet\Install-Package DiezX.Api.Commons -Version 1.12.0
<PackageReference Include="DiezX.Api.Commons" Version="1.12.0" />
<PackageVersion Include="DiezX.Api.Commons" Version="1.12.0" />
<PackageReference Include="DiezX.Api.Commons" />
paket add DiezX.Api.Commons --version 1.12.0
#r "nuget: DiezX.Api.Commons, 1.12.0"
#:package DiezX.Api.Commons@1.12.0
#addin nuget:?package=DiezX.Api.Commons&version=1.12.0
#tool nuget:?package=DiezX.Api.Commons&version=1.12.0
DiezX.Api.Commons
Este paquete central está equipado con clases esenciales diseñadas para apoyar el desarrollo de APIs RESTful utilizando el marco de desarrollo de DiezX. Proporciona herramientas y servicios comunes que se pueden utilizar a lo largo del proyecto.
Instalación
Instalación desde NuGet
La forma más sencilla de instalar la librería es a través del administrador de paquetes NuGet:
Usando la CLI de .NET:
dotnet add package DiezX.Api.CommonsUsando el Package Manager Console en Visual Studio:
Install-Package DiezX.Api.CommonsUsando el NuGet Package Manager en Visual Studio:
- Click derecho en el proyecto
- Seleccionar "Manage NuGet Packages..."
- Buscar "DiezX.Api.Commons"
- Click en "Install"
Dependencias del Proyecto
Este proyecto requiere las siguientes dependencias:
- NodaTime, versión
3.1.11 - MailKit, versión
4.16.0(actualizado para remediar CWE-74 Injection reportado por Snyk/Dependabot; previamente 4.15.1 por CVE-2026-30227 - CRLF Injection en MimeKit) - System.IdentityModel.Tokens.Jwt, versión
7.4.1 - MimeTypesMap, versión
1.0.8 - SonarAnalyzer.CSharp, versión
9.22.0.87781 - Otp.NET versión
1.4.0 - PreMailer.Net versión
2.6.0 - AngleSharp versión
1.1.0- Requerido paraHtmlSanitizer(parseo y saneamiento de HTML). - Microsoft.EntityFrameworkCore
7.0.18- Requerido para los métodos de extensión asincrónicos. Compatible con proyectos que usen EF Core 8.x. - BCrypt.Net-Next, versión
4.0.3- Requerido para HashingUtility (hashing de contraseñas).
Estructura del Proyecto
El proyecto está organizado en varias carpetas y archivos que se detallan a continuación:
Collections
CollectionUtil.cs: Utilidades para trabajar con colecciones de datos.Paginacion.cs: DTO con PageNumber y PageSize para parámetros de paginación en consultas.
Converters
JsonDateTimeConverter.cs: Convertidor para manejar la serialización de fechas en JSON.JsonValueConverters.cs: Fábrica de EF Core ValueConverter para columnas JSON (CreateNullableConverter<T>(),CreateJsonDocumentConverter()).
Date
DateUtil.cs: Utilidades para operaciones comunes relacionadas con fechas.
Html
HtmlSanitizer.cs: Sanitizador de HTML basado en lista blanca (default-deny) sobre el DOM de AngleSharp. Pensado para sanear cuerpos de correo o contenido de editores de texto enriquecido. ExponeHtmlSanitizer.Defaultpara uso inmediato.HtmlSanitizerOptions.cs: Configuración de la lista blanca (etiquetas, atributos, propiedades CSS y esquemas de URI permitidos) y de los límites anti-DoS (MaxInputLength,MaxDepth).
ExceptionHandlers
- Dtos
ExtendedProblemDetail.cs: Clase para proporcionar detalles adicionales en las respuestas de errores (RFC 7807), extendiendoProblemDetails.
- Exceptions
ApiGeneralException.cs: Excepción personalizada para errores generales de la API.ApiValidationParamsException.cs: Excepción para errores de validación de parámetros.TokenExpiredException.cs: Excepción cuando un token de autenticación ha expirado.DataNotFoundException.cs: Excepción cuando no se encuentran datos solicitados.
DefaultExceptionHandler.cs: Manejador por defecto para capturar y procesar excepciones. Extensible mediante herencia y el método virtualTryHandleCustomExceptionAsync(ver sección Extensibilidad del Exception Handler).- Filters
ValidateModelAttribute.cs: Filtro de acción para validar el modelo de entrada antes de llegar al controlador.
- Dtos
Notifications
- Configurations: Configuraciones relacionadas con notificaciones.
- Dto: Objetos de Transferencia de Datos para notificaciones.
- Services
DefaultMailSenderService.cs: Servicio predeterminado para enviar correos electrónicos.SendMailService.cs: Servicio para enviar correos electrónicos.
- Templates
EmailConfirmationTemplate.html: Plantilla para correos de confirmación.FirstPasswordTemplate.html: Plantilla para correos de primera contraseña.PasswordRecoveryTemplate.html: Plantilla para correos recuperación de contraseña.PasswordUpdatedTemplate.html: Plantilla para correos de actualización de contraseña.RejectionTemplate.html: Plantilla para correos donde se rechaza solicitud.MfaCodeEmailTemplate: Plantilla para enviar por correo código de MFA
- Utils
TemplateUtil.cs: Utilidades para trabajar con plantillas de correo electrónico.
Remote
RemoteUtils.cs: Clase de utilidades para manejar aspectos de las solicitudes remotas. Implementa un metodo para obtener la IP del usuario.
Resources
EmbeddedResourceUtil.cs: Utilidades para trabajar con recursos incrustados.StaticFileUtil.cs: Utilidades para trabajar con archivos estáticos.StreamUtils.cs: Utilidades para trabajar con flujos de datos.
Security
Configurations
CookieConfig.cs: Configuración para cookies de autenticación, define propiedades como nombres de cookies, tiempo de vida, y opciones de seguridad (HttpOnly, Secure, SameSite).MfaConfig.cs: Configuración para autenticación de doble factor, incluye parámetros como longitud del código, tiempo de expiración y opciones del algoritmo TOTP.TokenConfig.cs: Configuración para tokens JWT, define propiedades como secreto, tiempo de vida, y opciones de firma.
Controllers
AuthControllerBase.cs: Controlador base que proporciona funcionalidad común para respuestas de autenticación, incluyendo manejo de cookies seguras y respuestas adaptadas según el entorno.
Dto: Objetos de Transferencia de Datos para la seguridad.
Services
TokenService.cs: Servicio para la creación y manejo de tokens.UserRequestService.cs: Servicio para manejar solicitudes de usuario.MfaService: Servicio para MFA con TOTP, permitiendo generar y validar códigos basados en una clave secreta.
Utils
HeaderUtil.cs: Utileria para Decodificar la cabecera de autorización tipo BASIC y extraer las credenciales del usuario.RefreshTokenUtil: Utileria para la generación de Refresh Tokens seguros.AuthUtil.cs: Utilidad para gestión de autenticación que maneja cookies seguras para tokens JWT y refresh tokens, implementa configuraciones de seguridad (HttpOnly, Secure, SameSite) y adapta respuestas según el entorno (desarrollo/producción).HashingUtility.cs: Utilidad para hashear contraseñas (BCrypt), verificar hashes y generar API keys seguros.
Strings
StringUtil.cs: Utilidades para operaciones comunes con cadenas de texto.
Validators
AdvancedEmailAttribute.cs: Validador de atributo para la estructura y formato de direcciones de correo electrónico avanzadas (requiere que el correo tenga un dominio de primer nivel)DateRangeValidation.cs: Validador de atributo para asegurar que una fecha se encuentre dentro de un rango específico.FileExtensionAttribute.cs: Validador de atributo para verificar que un archivo tenga una de las extensiones de archivo permitidas.FileSizeAttribute.cs: Validador de atributo para el tamaño de un archivo, asegurando que no exceda un tamaño máximo especificado.PasswordValidationAttribute.cs: Validador de atributo para contraseñas, imponiendo reglas para una complejidad mínima requerida.
Extensiones
EnumerableExtensions.cs: Provee métodos de extensión paraIEnumerable<T>que permiten funcionalidades tales como lanzar excepciones personalizadas si el resultado de una consulta está vacía o una condición no se cumple.QueryableExtensions.cs: Métodos de extensión paraIQueryable<T>:Paginate(pageNumber, pageSize)yPaginate(Paginacion)para paginación de resultados.
Conventions
ApiConventions: Convención que incluye las posibles respuestas estándar del api para robustecer la documentación de swagger
Uso
Este proyecto está diseñado para ser utilizado como una biblioteca de clases dentro de un proyecto más grande de ASP.NET Core. Se debe hacer referencia a este proyecto desde su solución principal para acceder a las funcionalidades comunes que proporciona.
Extensibilidad del Exception Handler
DefaultExceptionHandler permite extender el manejo de excepciones mediante herencia. El método virtual TryHandleCustomExceptionAsync se invoca antes de la lógica estándar; si retorna un valor, se usa ese resultado; si retorna null, se delega al handler por defecto (que maneja ApiGeneralException, ApiValidationParamsException, TokenExpiredException, DataNotFoundException y errores genéricos).
Firma del método extensible
protected virtual Task<(ExtendedProblemDetail, LogLevel, string)?> TryHandleCustomExceptionAsync(Exception ex, HttpContext context)
- Retorno:
(ExtendedProblemDetail, LogLevel, string)?— tupla con el detalle del problema, nivel de log y mensaje para el log.nullpara delegar al handler estándar. - Parámetros:
exes la excepción capturada;contextpermite acceder alHttpContext(request, user, claims, etc.).
Ejemplo: manejo de excepciones propias del dominio
using DiezX.Api.Commons.ExceptionHandling;
using DiezX.Api.Commons.Utils;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
public class MiExceptionHandler : DiezX.Api.Commons.Exceptions.DefaultExceptionHandler
{
private readonly DateUtil _dateUtil;
public MiExceptionHandler(RequestDelegate next, DateUtil dateUtil, ILogger<MiExceptionHandler> logger, IOptions<JsonOptions> jsonOptions)
: base(next, dateUtil, logger, jsonOptions)
{
_dateUtil = dateUtil;
}
protected override Task<(ExtendedProblemDetail, LogLevel, string)?> TryHandleCustomExceptionAsync(Exception ex, HttpContext context)
{
if (ex is not MiExcepcionDominio miEx)
return Task.FromResult<(ExtendedProblemDetail, LogLevel, string)?>(null);
var mensaje = ObtenerMensajeSegunContexto(context, miEx);
var problemDetails = new ExtendedProblemDetail
{
Status = StatusCodes.Status503ServiceUnavailable,
Title = "ServiceUnavailable",
Detail = mensaje,
Timestamp = _dateUtil.GetTime(),
Instance = context.Request.Path
};
return Task.FromResult<(ExtendedProblemDetail, LogLevel, string)?>(
(problemDetails, LogLevel.Warning, $"Error dominio: {mensaje}"));
}
private static string ObtenerMensajeSegunContexto(HttpContext context, MiExcepcionDominio ex)
{
// Usar context.User para personalizar mensajes según rol/claims
if (context.User.IsInRole("Admin"))
return "Mensaje técnico para administrador.";
return "Mensaje genérico para el usuario.";
}
}
Escenario de uso
Problema: En un portal con integración a Power BI, cuando falla la conexión o el password expira, se quiere mostrar mensajes distintos según el tipo de usuario:
- Usuario interno: mensaje indicando que debe cambiar el password de Power BI en la configuración.
- Usuario externo: mensaje genérico ("Los tableros no están disponibles en este momento") para no exponer detalles internos.
Solución: Crear una excepción de dominio (PowerBIServiceException) con una propiedad IsPasswordExpired y un handler que extienda DefaultExceptionHandler. En TryHandleCustomExceptionAsync se detecta la excepción, se consulta context.User.IsInRole(...) para determinar el tipo de usuario y se devuelve el ExtendedProblemDetail con el mensaje correspondiente. De esta forma se evita consultar la base de datos y se usa el JWT ya disponible en el contexto.
Registro en Program.cs
Registra tu handler personalizado como middleware (reemplazando el manejo de excepciones por defecto si aplica):
app.UseMiddleware<MiExceptionHandler>();
El handler debe estar registrado en el pipeline antes de los middlewares que puedan lanzar excepciones. Las dependencias (DateUtil, ILogger, IOptions<JsonOptions>) se resuelven por inyección de dependencias.
Sanitización de HTML
HtmlSanitizer limpia HTML proveniente de entradas no confiables (p. ej. el mensaje de un editor de texto enriquecido que se insertará en el cuerpo de un correo) usando una lista blanca (default-deny) sobre el DOM parseado con AngleSharp. Conserva el formato permitido y descarta todo lo demás.
Uso básico
using DiezX.Api.Commons.Html;
var limpio = HtmlSanitizer.Default.Sanitize(htmlNoConfiable);
Uso con configuración personalizada
using DiezX.Api.Commons.Html;
var options = new HtmlSanitizerOptions
{
MaxInputLength = 50_000,
MaxDepth = 50,
ForceSafeExternalLinks = true
};
options.AllowedTags.Remove("a"); // p. ej. no permitir enlaces
options.AllowedCssProperties.Add("line-height");
var sanitizer = new HtmlSanitizer(options);
var limpio = sanitizer.Sanitize(htmlNoConfiable);
Qué hace
- Conserva una lista blanca de etiquetas de formato (
p,span,b/strong,i/em,u,ul/ol/li,a,blockquote, etc.). - Elimina etiquetas peligrosas y foreign content (
script,iframe,style,svg,math,template, …) junto con su contenido. - Quita todos los atributos no permitidos (incluidos los manejadores
on*). - Valida el esquema de
href(http/https/mailto) y fuerzatarget="_blank"+rel="noopener noreferrer". - Filtra el atributo
stylea las propiedades permitidas, bloqueandourl(),expression,javascript:y escapes CSS. - Aplica guardas anti-DoS: trunca entradas que exceden
MaxInputLengthy descarta subárboles más profundos queMaxDepth.
Alcance y límites
Está pensado para saneamiento del lado del servidor de HTML que se renderiza en clientes de correo o como contenido de confianza limitada. No sustituye a un sanitizador de DOM en el navegador (p. ej. DOMPurify). La instancia es inmutable tras construirse y puede reutilizarse de forma concurrente.
Contribuciones
Las contribuciones son bienvenidas siguiendo los estándares y lineamientos de DiezX.
DiezX.Api.Commons es un esfuerzo para proporcionar un punto de partida robusto y eficiente para el desarrollo de APIs con el marco de desarrollo DiezX.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net7.0
- AngleSharp (>= 1.1.0)
- BCrypt.Net-Next (>= 4.0.3)
- MailKit (>= 4.16.0)
- Microsoft.EntityFrameworkCore (>= 7.0.18)
- MimeTypesMap (>= 1.0.8)
- NodaTime (>= 3.1.11)
- Otp.NET (>= 1.4.0)
- PreMailer.Net (>= 2.6.0)
- System.IdentityModel.Tokens.Jwt (>= 7.4.1)
-
net8.0
- AngleSharp (>= 1.1.0)
- BCrypt.Net-Next (>= 4.0.3)
- MailKit (>= 4.16.0)
- Microsoft.EntityFrameworkCore (>= 7.0.18)
- MimeTypesMap (>= 1.0.8)
- NodaTime (>= 3.1.11)
- Otp.NET (>= 1.4.0)
- PreMailer.Net (>= 2.6.0)
- System.IdentityModel.Tokens.Jwt (>= 7.4.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.