Deux méthodes pour gérer l'upload de fichiers dans ASP.NET Core

Transfert de fichiers via formulaire (multipart/form-data)

Cete méthode repose sur le format multipart/form-data, couramment utilisé lorsqu’un utilisateur sélectionne un fichier via un champ de type <input type="file">. Le framewokr récupère automatiquement le fichier à travers une instance d’IFormFile.

Voici un exemple d’implémentation dans un contrôleur API :

[HttpPost]
[AllowAnonymous]
public IActionResult UploadViaForm(IFormFile uploadedFile)
{
    if (uploadedFile == null || uploadedFile.Length == 0)
        return BadRequest(new { status = "error", message = "Aucun fichier reçu." });

    var fileName = Path.GetFileNameWithoutExtension(uploadedFile.FileName);
    var fileExtension = Path.GetExtension(uploadedFile.FileName);
    var uniqueFileName = $"{Guid.NewGuid():N}_{fileName}{fileExtension}";
    var relativePath = $"/Uploads/{uniqueFileName}";
    var physicalPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", relativePath.TrimStart('/'));

    var directory = Path.GetDirectoryName(physicalPath);
    if (!Directory.Exists(directory))
        Directory.CreateDirectory(directory);

    using (var fileStream = new FileStream(physicalPath, FileMode.Create))
    {
        uploadedFile.CopyTo(fileStream);
    }

    var fileUrl = $"{_configuration["BaseUrl"]}{relativePath}";
    var response = new
    {
        name = uploadedFile.FileName,
        status = "success",
        thumbnailUrl = fileUrl,
        url = fileUrl
    };

    return Ok(response);
}

Dans Postman ou tout client HTTP, il suffit de définir le header Content-Type: multipart/form-data et d’envoyer le fichier dans un champ nommé uploadedFile.

Envoi de données binaires brutes (raw binary)

L’autre approche consiste à envoyer directement le contenu binaire du fichier dans le corps de la requête, sans passer par un formulaire. Cette technique est utile pour les clients qui envoient des flux bruts (comme certaines applications mobiles ou scripts).

Le serveur lit alors le flux d’entrée directement depuis HttpContext.Request.Body. Attention : par défaut, .NET désactive les opérations synchrones sur les flux. Si vous rencontrez une exception liée à AllowSynchronousIO, configurez votre service comme suit :

builder.Services.Configure<KestrelServerOptions>(options =>
{
    options.AllowSynchronousIO = true;
});

Voici un exemple de traitement d'image envoyée en binaire :

[HttpPost]
[AllowAnonymous]
public async Task<IActionResult> UploadRawImage()
{
    var content = HttpContext.Request.Body;
    var memoryStream = new MemoryStream();

    await content.CopyToAsync(memoryStream);
    memoryStream.Position = 0;

    // Optionnel : validation du type MIME
    var imageInfo = SixLabors.ImageSharp.Image.Identify(memoryStream);
    if (imageInfo == null)
        return BadRequest("Format d'image invalide.");

    memoryStream.Position = 0;
    return File(memoryStream, "image/jpeg");
}

Transformation d'miages à la volée avec ImageSharp

À partir d’ASP.NET Core 7, il est possible de manipuler des images directement depuis le système de fichiers ou un flux entrant. En utilisant la bibliothèque SixLabors.ImageSharp, on peut redimensionner, compresser ou convertir des images dynamiquement.

Exemple : redimensionnement d’une image stockée localement :

using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Processing;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/thumbnail/{imageName}", async (string imageName, HttpContext context) =>
{
    var imagePath = Path.Combine(builder.Environment.WebRootPath, "img", imageName);

    if (!System.IO.File.Exists(imagePath))
        return Results.NotFound();

    context.Response.Headers.Cache-Control = "public, max-age=86400";

    return Results.Stream(async stream =>
    {
        using var image = await Image.LoadAsync(imagePath);
        image.Mutate(x => x.Resize(new ResizeOptions
        {
            Size = new Size(image.Width / 2, image.Height / 2),
            Mode = ResizeMode.Max
        }));

        await image.SaveAsJpegAsync(stream, new JpegEncoder(), default);
    }, "image/jpeg");
});

app.Run();

Ce genre de route permet de servir des miniatures générées à la demande, avec mise en cache côté client.

Gestion de plusieurs fichiers

Pour transférer plusieurs fichiers simultanément, remplacez IFormFile par IFormFileCollection dans les paramètres de l'action du contrôleur. Par exemple :

[HttpPost]
public IActionResult UploadMultiple(IFormFileCollection files)
{
    foreach (var file in files)
    {
        // Traiter chaque fichier comme ci-dessus
    }
    return Ok();
}

La logique reste similaire, mais itérative.

Étiquettes: ASP.NET Core IFormFile Binary Upload ImageSharp File Upload

Publié le 4 août à 02h27