177 votes

Retourner le fichier dans ASP.Net Core Web API

Problème

Je souhaite renvoyer un fichier dans mon contrôleur ASP.Net Web API, mais toutes mes approches renvoient le fichier HttpResponseMessage en tant que JSON.

Code jusqu'à présent

public async Task<HttpResponseMessage> DownloadAsync(string id)
{
    var response = new HttpResponseMessage(HttpStatusCode.OK);
    response.Content = new StreamContent({{__insert_stream_here__}});
    response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
    return response;
}

Lorsque j'appelle ce point de terminaison dans mon navigateur, l'API Web renvoie l'adresse suivante HttpResponseMessage en tant que JSON avec l'en-tête de contenu HTTP réglé sur application/json .

303voto

Nkosi Points 95895

S'il s'agit d'ASP.net-Core, vous mélangez les versions de l'API Web. Faites en sorte que l'action renvoie un fichier dérivé IActionResult car dans votre code actuel, le framework traite HttpResponseMessage comme modèle.

[Route("api/[controller]")]
public class DownloadController : Controller {
    //GET api/download/12345abc
    [HttpGet("{id}")]
    public async Task<IActionResult> Download(string id) {
        Stream stream = await {{__get_stream_based_on_id_here__}}

        if(stream == null)
            return NotFound(); // returns a NotFoundResult with Status404NotFound response.

        return File(stream, "application/octet-stream"); // returns a FileStreamResult
    }    
}

24 votes

Dans mon cas, j'avais besoin de rendre un Excel en mémoire et de le renvoyer pour téléchargement, donc j'avais besoin de définir un nom de fichier avec une extension également : return File(stream, "application/octet-stream", "filename.xlsx"); Ainsi, lorsqu'il est téléchargé, l'utilisateur peut l'ouvrir directement.

0 votes

Je comprends ce que le NotFound() En fin de compte, c'est le cas, mais réside-t-il dans .NET Core ou est-ce quelque chose de local dans votre projet ?

2 votes

@megaMan c'est une méthode d'aide sur ControllerBase et fait partie du cadre lui-même docs.microsoft.com/fr/us/dotnet/api/

38voto

Hamed Naeemaei Points 771

Vous pouvez renvoyer FileResult avec ces méthodes :

1 : Retourner FileStreamResult

    [HttpGet("get-file-stream/{id}"]
    public async Task<FileStreamResult> DownloadAsync(string id)
    {
        var fileName="myfileName.txt";
        var mimeType="application/...."; 
        var stream = await GetFileStreamById(id);

        return new FileStreamResult(stream, mimeType)
        {
            FileDownloadName = fileName
        };
    }

2 : Retourner FileContentResult

    [HttpGet("get-file-content/{id}"]
    public async Task<FileContentResult> DownloadAsync(string id)
    {
        var fileName="myfileName.txt";
        var mimeType="application/...."; 
        var fileBytes = await GetFileBytesById(id);

        return new FileContentResult(fileBytes, mimeType)
        {
            FileDownloadName = fileName
        };
    }

24voto

Fase Points 490

Voici un exemple simpliste de diffusion d'un fichier :

using System.IO;
using Microsoft.AspNetCore.Mvc;

[HttpGet("{id}")]
public async Task<FileStreamResult> Download(int id)
{
    var path = "<Get the file path using the ID>";
    var stream = File.OpenRead(path);
    return new FileStreamResult(stream, "application/octet-stream");
}

Note :

Veillez à utiliser FileStreamResult de Microsoft.AspNetCore.Mvc et pas de System.Web.Mvc .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X