Almacenamiento S3
Sube, descarga y firma objetos en S3/MinIO desde .NET con DinaS3ClientC, y replica en varios buckets con DinaS3MultiClientC.
El módulo S3 del paquete Dinaup habla con cualquier almacén compatible con S3 (AWS S3, MinIO) sobre el cliente de Minio. Ofrece dos clientes: uno para un bucket (DinaS3ClientC) y otro que replica y repara sobre varios (DinaS3MultiClientC).
using Dinaup;Un bucket: DinaS3ClientC
Conectar
var s3 = new DinaS3ClientC(
_s3Token: "ACCESS_KEY",
_s3Secret: "SECRET_KEY",
_s3EndPoint: "s3.tu-dominio.com",
_Bucket: "mi-bucket",
_BaseDir: "app/"); // prefijo opcional dentro del bucket
// También por cadena de conexión o diccionario de parámetros:
var s3b = new DinaS3ClientC("s3://ACCESS:SECRET@s3.tu-dominio.com/mi-bucket");Operar con objetos
Las rutas son relativas al bucket (y al _BaseDir si lo fijaste).
// Subir bytes
await s3.BytesUploadAsync("informes/2026-07.json", contenidoBytes);
// Descargar bytes
byte[] datos = await s3.BytesReadAsync("informes/2026-07.json");
// Comprobar si existe
bool hay = await s3.FileExistAsync("informes/2026-07.json");
// Subir y descargar archivos de disco
await s3.FileUploadAsync("informes/2026-07.pdf", @"C:\temp\informe.pdf");
await s3.FileDownloadAsync("informes/2026-07.pdf", @"C:\temp\bajado.pdf");
// Sube solo si el contenido difiere del que ya hay
await s3.FileUploadIfIsDifferentAsync("logo.png", @"C:\assets\logo.png");
// Listar
var items = await s3.FileList("informes/", recursive: true);
// Borrar
await s3.FileRemoveAsync("informes/2026-07.json");URLs firmadas
Genera URLs temporales de lectura o de subida sin exponer las claves.
// Lectura: expira en 600 s por defecto
string urlLectura = s3.SignGet("informes/2026-07.pdf", expirationSeconds: 600);
// Escritura directa desde el navegador
string urlSubida = s3.SignPut("subidas/nuevo.pdf", expirationSeconds: 600);Salud
bool ok = await s3.HealthCheckAsync();DinaS3ClientC también implementa IHealthCheck de Microsoft.Extensions.Diagnostics.HealthChecks, así que se registra directamente en el health-check de ASP.NET Core.
Varios buckets: DinaS3MultiClientC
Envuelve una lista de DinaS3ClientC y opera sobre todos: escribe en todos, lee del primero que responde y, si detecta que a un bucket le falta un objeto, lo repara desde otro.
var multi = new DinaS3MultiClientC(
new List<DinaS3ClientC> { s3Primario, s3Secundario },
_autoRepair: true);
// Escribe en todos los buckets
var res = await multi.WriteBytesAsync("informes/2026-07.json", datos);
// Lee del primero disponible
byte[] leido = await multi.ReadBytesAsync("informes/2026-07.json");
// Objetos serializados en JSON
await multi.WriteObjectAsync("config/app.json", miConfig);
var config = await multi.ReadObjectAsync<AppConfig>("config/app.json");
// Existencia, listado, archivos y borrado, igual que el cliente simple
bool hay = await multi.ExistsAsync("informes/2026-07.json");
var items = await multi.ListAsync("informes/", recursive: true);Reparación y deriva
// Reparar un objeto concreto: lo copia a los buckets que no lo tengan
await multi.RepairAsync("informes/2026-07.json");
// Salud global
bool ok = await multi.HealthCheckAsync();
// Detectar deriva entre buckets sobre una muestra
var drift = await multi.CheckDriftAsync("informes/", sampleCount: 50);
if (drift.HasDrift)
Console.WriteLine($"{drift.Drifted.Count} objetos difieren entre buckets");CheckDriftAsync devuelve un DriftReport con TotalChecked, InSync, Drifted (rutas que difieren) y Missing (por bucket, qué falta). Igual que el cliente simple, DinaS3MultiClientC implementa IHealthCheck.
La replicación no es transaccional: WriteBytesAsync intenta escribir en todos los buckets y te informa del resultado por bucket. La reparación automática cierra los huecos cuando una lectura detecta que a un bucket le falta el objeto.