FEPBA.Helper 10.2.0

dotnet add package FEPBA.Helper --version 10.2.0
                    
NuGet\Install-Package FEPBA.Helper -Version 10.2.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="FEPBA.Helper" Version="10.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="FEPBA.Helper" Version="10.2.0" />
                    
Directory.Packages.props
<PackageReference Include="FEPBA.Helper" />
                    
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 FEPBA.Helper --version 10.2.0
                    
#r "nuget: FEPBA.Helper, 10.2.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 FEPBA.Helper@10.2.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=FEPBA.Helper&version=10.2.0
                    
Install as a Cake Addin
#tool nuget:?package=FEPBA.Helper&version=10.2.0
                    
Install as a Cake Tool

FEPBA.Helper

NuGet Version License: MIT .NET

🌐 Documentation Language Selection | English

Tabla de Contenidos

Descripción General

FEPBA.Helper es una librería comprehensiva para .NET 10.0 que proporciona utilidades esenciales para aplicaciones ASP.NET Core, incluyendo:

  • Gestión de Base de Datos: Ejecución de stored procedures en SQL Server con capacidades de registro de logs
  • Cliente HTTP Proxy: Comunicación REST API con registro de logs integrado y manejo de errores
  • Controladores Personalizados: Clases base para ASP.NET Core con manejo de excepciones
  • Modelos de Respuesta: Formatos estandarizados para respuestas de API

Esta librería está especialmente diseñada para ser utilizada por FEPBA, facilitando el desarrollo de aplicaciones web robustas y escalables.

Instalación

Prerrequisitos

  • .NET 10.0 o superior
  • Visual Studio 2022 o VS Code
  • SQL Server (para funcionalidades de base de datos)

Instalación via NuGet

Instala el paquete a través del Administrador de paquetes NuGet:

Install-Package FEPBA.Helper

O usando la CLI de .NET:

dotnet add package FEPBA.Helper

Inicio Rápido

1. Configuración en Program.cs

using FEPBA.Helper;
using FEPBA.Helper.Custom;

var builder = WebApplication.CreateBuilder(args);

// Servicios requeridos
builder.Services.AddHttpClient();
builder.Services.AddScoped<ICustomLogger, CustomLogger>();
builder.Services.AddExceptionHandler<CustomExceptionHandler>();
builder.Services.AddProblemDetails();

var app = builder.Build();

// Middleware (antes de UseRouting)
app.UseMiddleware<ResponseCaptureMiddleware>();
app.UseExceptionHandler();

app.Run();

2. Configuración en appsettings.json

{
  "SQLServerLogger": {
    "ConnectionStrings": "cadena de conexión",
    "IsActive": true,
    "Include200": false,
    "ProcedureName": "procedure",
    "TrackMethods": ["GET", "POST"],
    "TrackService": ["MiServicio"],
    "ForceTrackMethods": ["POST"],
    "ForceTrackService": ["ServicioCrítico"],
    "IgnoreMethods": ["GET"],
    "IgnoreService": ["ServicioNoCrítico"]
  },
  "CustomLogger": {
    "ConnectionStrings": "cadena de conexión",
    "IsActive": true,
    "Include200": true,
    "ProcedureName": "procedure",
    "TrackMethods": [],
    "TrackService": [],
    "ForceTrackMethods": [],
    "ForceTrackService": [],
    "IgnoreMethods": [],
    "IgnoreService": []
  }
}

3. Uso Básico del Cliente HTTP

using FEPBA.Helper.WebClientProxy;

public class MiController : CustomController
{
    private readonly ProxyHttpClient _restHelper;

    public MiController(IConfiguration configuration)
    {
        _restHelper = new ProxyHttpClient(configuration);
    }

    public IActionResult GetData()
    {
        var response = _restHelper.RestCallGet("https://api.ejemplo.com/data", this);
        return response;
    }

    public IActionResult PostData(object data)
    {
        var response = _restHelper.RestCallPost("https://api.ejemplo.com/data", data, this);
        return response;
    }
}

Características

Gestión de Base de Datos

Arquitectura Modular

La librería utiliza una arquitectura basada en clases abstractas para mayor flexibilidad:

  • DbManagerBase: Clase abstracta base con toda la funcionalidad común
  • DbManager: Implementación concreta que usa CustomDbContext con connection string
  • DbManagerContext: Implementación que usa DbContextOptions para inyección de dependencias
  • CustomDbContext: DbContext personalizado con configuración de timeout
DbManager

La librería proporciona opciones avanzadas para la ejecución de stored procedures:

  • Timeout Personalizable: Modificar el tiempo límite antes de que se levante el error de Timeout al ejecutar stored procedures. El parámetro es opcional en los constructores.
  • Precisión en Nombres: Modificar el porcentaje de precisión para la comparación de los nombres de las propiedades. El parámetro es opcional en los constructores.
  • Logging de Ejecuciones: Ejecutar un stored procedure para usar un Log de todas las ejecuciones. Es necesario usar la sobrecarga del constructor que recibe como parámetros:
    • string de conexión
    • nombre del stored procedure a ejecutar
    • booleano para activar la ejecución del Log

El stored procedure de Log debe aceptar como parámetros:

  • string procedureName: nombre del stored procedure ejecutado previo
  • int ExecuteTime: tiempo de ejecución en milisegundos
using FEPBA.Helper.DB;

// Constructor básico
var dbManager = new DbManager(connectionString);

// Constructor con logging
var dbManagerWithLog = new DbManager(connectionString, logConnectionString, "LogProcedure", true);

// Constructor con timeout y precisión personalizadas
var dbManagerCustom = new DbManager(connectionString, timeoutChange: 60, precisionChange: 0.95);
Uso de DbManagerContext (Inyección de Dependencias)
using FEPBA.Helper.DB;

// Configuración en Program.cs para inyección de dependencias
builder.Services.AddDbContext<CustomDbContext>(options =>
    options.UseSqlServer(connectionString));

// Uso en un servicio con inyección de dependencias
public class MiServicio
{
    private readonly DbManagerContext _dbManager;

    public MiServicio(DbContextOptions<CustomDbContext> options)
    {
        _dbManager = new DbManagerContext(options);
    }
}
Uso de DbManagerContextFactory (DbContextFactory Pattern)
using FEPBA.Helper.DB;

// Configuración en Program.cs para DbContextFactory
builder.Services.AddDbContextFactory<CustomDbContext>(options =>
    options.UseSqlServer(connectionString));

// Uso en un servicio con DbContextFactory
public class MiServicio
{
    private readonly DbManagerContextFactory _dbManagerFactory;

    public MiServicio(IDbContextFactory<CustomDbContext> contextFactory)
    {
        _dbManagerFactory = new DbManagerContextFactory(contextFactory);
    }
}

Ventajas de DbManagerContextFactory:

  • Mejor Concurrencia: Cada operación usa su propio DbContext
  • Connection Pooling Optimizado: Liberación inmediata de conexiones
  • Ideal para Singleton Services: Perfecto para servicios de larga duración
  • Alto Throughput: Mejor rendimiento para operaciones concurrentes
DbParameter

Te permite armar la lista de parámetros para tus store procedures con código más limpio:

var parameters = new List<DbParameter>();
DbParameter.AddInputParameter(ref parameters, new Dictionary<string, object>()
{
    { "Nombre", "Juan Pérez" },
    { "Edad", 30 },
    { "FechaNacimiento", fechaNacimiento ?? DBNull.Value }
});

Cliente HTTP Proxy

Métodos Síncronos
// GET
var getResponse = _restHelper.RestCallGet(url, controller);
var (getResponse, content) = _restHelper.RestCallGet(url, controller, out content);

// POST
var postResponse = _restHelper.RestCallPost(url, body, controller);
var (postResponse, postContent) = _restHelper.RestCallPost(url, body, controller, out postContent);

// Descarga de archivos
var fileResponse = _restHelper.RestCallGetFileDownload(url, controller, "archivo.pdf", "application/pdf");
Métodos Asíncronos
// GET asíncrono
var getResponse = await _restHelper.RestCallGetAsync(url, controller);
var (getResponse, content) = await _restHelper.RestCallGetContentAsync(url, controller);

// POST asíncrono
var postResponse = await _restHelper.RestCallPostAsync(url, body, controller);
var (postResponse, postContent) = await _restHelper.RestCallPostContentAsync(url, body, controller);

Referencia de API

DbManager

Constructores
public DbManager(string connectionString, int? timeoutChange = null, double? precisionChange = null)
public DbManager(string connectionString, string logString, string logProcedure, bool? flagLog = null, int? timeoutChange = null, double? precisionChange = null)
Propiedades
  • ConnectionString: Cadena de conexión a la base de datos
  • TimeoutLimit: Tiempo límite de ejecución en segundos (default: 30)
  • NamePrecisionPercentage: Porcentaje de precisión para comparación de nombres (default: 0.8)

ProxyHttpClient

Métodos Principales
IActionResult RestCallGet(string uri, Controller api, Dictionary<string, string> headersSend = null)
IActionResult RestCallPost(string uri, object body, Controller api, Dictionary<string, string> headersSend = null)
Task<IActionResult> RestCallGetAsync(string url, Controller api, Dictionary<string, string> headersSend = null)
Task<IActionResult> RestCallPostAsync(string url, object body, Controller api, Dictionary<string, string> headersSend = null)

ResponseApi

public class ResponseApi<T> where T : class
{
    public HttpStatusCode ok { get; set; }
    public string message { get; set; }
    public T data { get; set; }
    public string developerMessage { get; set; }
    public int errorCode { get; set; }
    public string exception { get; set; }
}

Configuración

Estructura de appsettings.json

SQLServerLogger
{
  "SQLServerLogger": {
    "ConnectionStrings": "cadena de conexión",
    "IsActive": true,
    "Include200": false,
    "ProcedureName": "procedure",
    "TrackMethods": ["GET", "POST"],
    "TrackService": ["MiServicio"],
    "ForceTrackMethods": ["POST"],
    "ForceTrackService": ["ServicioCrítico"],
    "IgnoreMethods": ["GET"],
    "IgnoreService": ["ServicioNoCrítico"]
  },
  "CustomLogger": {
    "ConnectionStrings": "cadena de conexión",
    "IsActive": true,
    "Include200": true,
    "ProcedureName": "procedure",
    "TrackMethods": [],
    "TrackService": [],
    "ForceTrackMethods": [],
    "ForceTrackService": [],
    "IgnoreMethods": [],
    "IgnoreService": []
  }
}
ErrorHandling (Opcional)

Opcionalmente se puede agregar en el archivo appsettings.json una sección llamada "ErrorHandling" para guardar mensajes predefinidos para los códigos de error HTTP:

{
  "ErrorHandling": {
    "404": "Recurso no encontrado",
    "418": "Soy una tetera",
    "500": "Error interno del servidor"
  }
}

Store Procedure para Logging

El Proxy utiliza un store procedure con estos campos:

CREATE PROCEDURE [dbo].[AddRequestResposeLog] 
    @Username [varchar](100) NULL,
    @RequestMethod [varchar](100) NULL,
    @UrlRequestFrontend [varchar](100) NULL,
    @UrlRequestBackend [varchar](100) = NULL,
    @QueryString [varchar](100) = NULL,
    @RequestHeaders [nvarchar](max) NULL,
    @RequestBody [nvarchar](max) = NULL,
    @FrontendException [nvarchar](max) = NULL,
    @BackendResponse [nvarchar](max) = NULL,
    @StatusCode [int] NULL,
    @new_identity INT = NULL OUTPUT
AS
BEGIN
    SET NOCOUNT ON;
    
    INSERT INTO [dbo].[Logger]
           ([Username], [RequestMethod], [UrlRequestFrontend], [UrlRequestBackend], 
            [QueryString], [RequestHeaders], [RequestBody], [FrontendException], 
            [BackendResponse], [StatusCode])
    VALUES
           (@Username, @RequestMethod, @UrlRequestFrontend, @UrlRequestBackend, 
            @QueryString, @RequestHeaders, @RequestBody, @FrontendException, 
            @BackendResponse, @StatusCode);

    SET @new_identity = SCOPE_IDENTITY();
    SELECT @new_identity as N'New_Identity'
END

Migration Guide

From Previous Architecture

Si estabas usando una versión anterior de FEPBA.Helper, así es cómo migrar a la nueva arquitectura modular:

Código Antiguo (Versión Anterior)
// Anteriormente podías tener algo como esto
var context = new DbManagerContext(connectionString);
Código Nuevo (Versión Actual)
// Opción 1: Usar DbManager con connection string (recomendado)
var dbManager = new DbManager(connectionString);

// Opción 2: Usar DbManagerContext con DbContextOptions (para inyección de dependencias)
var dbManager = new DbManagerContext(options);
Beneficios de la Migración
  1. Mejor Separación de Responsabilidades: DbManagerBase maneja toda la lógica común
  2. Arquitectura Flexible: Elegir entre connection string o inyección de dependencias
  3. Mejor Capacidad de Prueba: Más fácil de simular y hacer pruebas unitarias
Cambios Ruptores
  • DbManagerContext ahora extiende DbManagerBase en lugar de implementación directa
  • Las firmas de los constructores han sido actualizadas para una mayor flexibilidad

Ejemplos

Ejemplo Completo: Controlador de API

using Microsoft.AspNetCore.Mvc;
using FEPBA.Helper.Custom;
using FEPBA.Helper.WebClientProxy;
using FEPBA.Helper.Models;

[ApiController]
[Route("api/[controller]")]
public class UsuariosController : CustomController
{
    private readonly ProxyHttpClient _restHelper;
    private readonly DbManager _dbManager;

    public UsuariosController(IConfiguration configuration)
    {
        _restHelper = new ProxyHttpClient(configuration);
        _dbManager = new DbManager(configuration.GetConnectionString("DefaultConnection"));
    }

    [HttpGet]
    public async Task<IActionResult> GetUsuarios()
    {
        try
        {
            var response = await _restHelper.RestCallGetAsync("https://api.externa.com/usuarios", this);
            return response;
        }
        catch (Exception ex)
        {
            return CustomErrorStatusCode(new CustomException("Error al obtener usuarios", 1001, ex));
        }
    }

    [HttpPost]
    public IActionResult CrearUsuario([FromBody] Usuario usuario)
    {
        try
        {
            var parameters = new List<DbParameter>();
            DbParameter.AddInputParameter(ref parameters, new Dictionary<string, object>()
            {
                { "Nombre", usuario.Nombre },
                { "Email", usuario.Email },
                { "FechaCreacion", DateTime.Now }
            });

            var result = _dbManager.ExecuteProcedure("CrearUsuario", parameters);
            
            return Ok(new ResponseApi<object>(HttpStatusCode.OK, "Usuario creado exitosamente", result));
        }
        catch (Exception ex)
        {
            return CustomErrorStatusCode(new CustomException("Error al crear usuario", 1002, ex));
        }
    }
}

Ejemplos de Uso del Cliente HTTP

// Ejemplo de una petición GET
var logGetResponse = restHelper.RestCallGet(urilogGet, this);

// Ejemplo de una petición POST
// En este ejemplo se hace una petición POST para enviar un email
Mail mail = new Mail()
{
    To = "mail@ejemplo.com",
    Subject = "Rellena con tu subject",
    Body = bodyHtml,
    HTML = true,
    From = "no-responder@fepba.gov.ar"
};
var PostResponse = restHelperEnviar.RestCallPost(uri, mail, this);

Formato de Respuestas

Maneja las respuestas de las peticiones y los errores según tus necesidades. Nuestras respuestas suelen ser JSON con el siguiente formato:

{
  "ok": "STATUS CODE",
  "data": "DATA DE LA RESPUESTA",
  "message": "MENSAJE DE LA RESPUESTA"
};

Ejemplo: Manejo de Errores Personalizado

using FEPBA.Helper.Custom;

public class MiServicio
{
    public void ValidarDatos(Datos datos)
    {
        if (datos == null)
            throw new CustomException("Los datos son requeridos", 2001);
        
        if (string.IsNullOrEmpty(datos.Nombre))
            throw new CustomException("El nombre es requerido", 2002);
        
        if (datos.Edad < 18)
            throw new CustomException("El usuario debe ser mayor de edad", 2003);
    }
}

Troubleshooting

Problemas Comunes

1. Timeout en Stored Procedures

Problema: Las operaciones de base de datos exceden el tiempo límite.

Solución:

var dbManager = new DbManager(connectionString, timeoutChange: 120); // 2 minutos
2. Errores de Conexión HTTP

Problema: Fallos en llamadas a APIs externas.

Solución:

// Agregar headers personalizados
var headers = new Dictionary<string, string>
{
    { "Authorization", "Bearer token" },
    { "User-Agent", "MiApp/1.0" }
};
var response = _restHelper.RestCallGet(url, this, headers);
3. Problemas de Logging

Problema: No se registran las llamadas en la base de datos.

Solución:

  • Verificar que IsActive esté en true
  • Comprobar la cadena de conexión
  • Validar que el stored procedure exista
4. Errores de Serialización JSON

Problema: Los objetos no se serializan correctamente.

Solución:

// Usar atributos de Newtonsoft.Json
[JsonObject(MemberSerialization.OptIn)]
public class MiObjeto
{
    [JsonProperty("nombre")]
    public string Nombre { get; set; }
}

Preguntas Frecuentes

Q: ¿Cómo deshabilitar el logging? A: Establecer IsActive: false en la configuración del logger.

Q: ¿Cómo manejar respuestas que no son JSON? A: Usar los métodos que devuelven string para obtener el contenido crudo.

Q: ¿Es compatible con .NET 8? A: La clase HttpHelperRestConections será eliminada en .NET 8+, pero ProxyHttpClient es compatible.

Style Guidelines

  • Seguir las convenciones de C# de Microsoft
  • Agregar pruebas unitarias para nuevas funcionalidades
  • Documentar código público con XML comments
  • Mantener compatibilidad con .NET 10.0

Local Development

# Restaurar paquetes
dotnet restore

# Compilar solución
dotnet build

# Ejecutar pruebas
dotnet test

License

Este proyecto está licenciado bajo la Licencia MIT. Ver el archivo LICENSE para más detalles.

Credits

Autores: Mauricio Agosta, Lautaro Petrigh

Equipo de Informática de FEPBA


Nota Importante: La clase HttpHelperRestConections será eliminada en versiones futuras (.NET 8+). Se recomienda migrar a ProxyHttpClient.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  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
10.2.0 98 3/12/2026
10.1.3 88 3/11/2026
10.1.3-alpha 87 2/13/2026
10.1.2 113 2/10/2026
10.0.1 100 2/5/2026
10.0.0 119 1/8/2026
8.13.2 104 2/10/2026
8.12.1 180 2/5/2026
8.12.0 117 1/8/2026
8.11.3 687 12/3/2025
8.11.2 217 10/29/2025
8.11.1 209 10/28/2025
8.11.0 203 10/9/2025
8.10.0 212 10/1/2025
6.11.1 201 10/28/2025
6.11.0 189 10/9/2025
Loading failed

Cambio para usar EntityFrameworkCore