Cómo crear un sistema de archivos y subida de imágenes en ASP.NET Core

En cualquier aplicación web moderna es común permitir que los usuarios suban imágenes, documentos o archivos. ASP.NET Core ofrece herramientas muy completas para implementar esta funcionalidad de forma segura, escalable y sencilla.

Lo primero es crear un endpoint que reciba archivos mediante IFormFile. Esta interfaz representa el archivo enviado desde un formulario HTML o desde una petición HTTP utilizando multipart/form-data.

Un ejemplo básico sería:

[HttpPost("upload")]
public async Task<IActionResult> Upload(IFormFile file)
{
    if (file == null || file.Length == 0)
        return BadRequest("No se recibió ningún archivo.");

    var uploadsPath = Path.Combine(
        Directory.GetCurrentDirectory(),
        "wwwroot",
        "uploads");

    Directory.CreateDirectory(uploadsPath);

    var fileName = Guid.NewGuid() + Path.GetExtension(file.FileName);

    var filePath = Path.Combine(uploadsPath, fileName);

    using var stream = new FileStream(filePath, FileMode.Create);

    await file.CopyToAsync(stream);

    return Ok(new
    {
        FileName = fileName,
        Url = $"/uploads/{fileName}"
    });
}

Una de las mejores prácticas consiste en nunca guardar el nombre original del archivo. Utilizar un GUID evita conflictos cuando distintos usuarios suben imágenes con el mismo nombre y dificulta ataques basados en nombres predecibles.

También es importante validar el archivo antes de almacenarlo. Algunas validaciones recomendadas incluyen:

  • Verificar el tamaño máximo permitido.
  • Permitir únicamente extensiones autorizadas (.jpg, .png, .webp, etc.).
  • Validar el tipo MIME.
  • Evitar archivos ejecutables.
  • Analizar archivos con un antivirus si la aplicación lo requiere.

Por ejemplo:

var allowedExtensions = new[] { ".jpg", ".jpeg", ".png", ".webp" };

var extension = Path.GetExtension(file.FileName).ToLower();

if (!allowedExtensions.Contains(extension))
    return BadRequest("Formato no permitido.");

ASP.NET Core puede servir archivos estáticos desde la carpeta wwwroot utilizando:

app.UseStaticFiles();

De esta manera las imágenes almacenadas en wwwroot/uploads podrán accederse mediante una URL como:

https://misitio.com/uploads/imagen.jpg

Sin embargo, en aplicaciones empresariales normalmente no se recomienda almacenar toda la información en el servidor local, especialmente si la aplicación se ejecuta en múltiples instancias o contenedores. En esos casos resulta mucho mejor utilizar servicios de almacenamiento como Azure Blob Storage, Amazon S3 o Cloudinary, donde los archivos permanecen disponibles incluso si el servidor se reinicia o se despliega una nueva versión.

Otro aspecto importante es guardar únicamente la información necesaria en la base de datos, por ejemplo:

  • Nombre generado.
  • Nombre original.
  • Ruta o URL.
  • Tamaño.
  • Tipo de archivo.
  • Fecha de carga.
  • Usuario que realizó la subida.

Así se mantiene la base de datos ligera mientras los archivos permanecen almacenados en un sistema especializado.

Finalmente, recuerda proteger los endpoints de subida con autenticación y autorización cuando sea necesario. Además, limita el tamaño de los archivos mediante la configuración de ASP.NET Core y registra cualquier error durante la carga utilizando un sistema de logging.

Implementar correctamente un sistema de subida de archivos no solo mejora la experiencia del usuario, sino que también incrementa la seguridad, el rendimiento y la escalabilidad de tu aplicación. Siguiendo estas buenas prácticas podrás construir una solución robusta, preparada para proyectos empresariales y fácil de mantener a medida que tu aplicación crezca.

Te puede interesar...

Deja un comentario