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
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="DiezX.Api.Commons" Version="1.12.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="DiezX.Api.Commons" Version="1.12.0" />
                    
Directory.Packages.props
<PackageReference Include="DiezX.Api.Commons" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add DiezX.Api.Commons --version 1.12.0
                    
#r "nuget: DiezX.Api.Commons, 1.12.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package DiezX.Api.Commons@1.12.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=DiezX.Api.Commons&version=1.12.0
                    
Install as a Cake Addin
#tool nuget:?package=DiezX.Api.Commons&version=1.12.0
                    
Install as a Cake Tool

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:

  1. Usando la CLI de .NET:

    dotnet add package DiezX.Api.Commons
    
  2. Usando el Package Manager Console en Visual Studio:

    Install-Package DiezX.Api.Commons
    
  3. Usando 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 para HtmlSanitizer (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. Expone HtmlSanitizer.Default para 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), extendiendo ProblemDetails.
    • 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 virtual TryHandleCustomExceptionAsync (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.
  • 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 para IEnumerable<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 para IQueryable<T>: Paginate(pageNumber, pageSize) y Paginate(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. null para delegar al handler estándar.
  • Parámetros: ex es la excepción capturada; context permite acceder al HttpContext (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 fuerza target="_blank" + rel="noopener noreferrer".
  • Filtra el atributo style a las propiedades permitidas, bloqueando url(), expression, javascript: y escapes CSS.
  • Aplica guardas anti-DoS: trunca entradas que exceden MaxInputLength y descarta subárboles más profundos que MaxDepth.

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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.12.0 40 6/6/2026
1.11.2 154 4/22/2026
1.11.1 130 3/14/2026
1.10.0 120 2/20/2026
1.9.0 311 12/17/2025
1.8.0 274 10/15/2025
1.7.1 632 7/22/2025
1.3.0 546 4/27/2024
1.2.1 252 3/21/2024
1.1.1 253 3/5/2024
1.1.0 299 12/19/2023
1.0.0 252 11/11/2023