ASP.Net Core Web API'de dosya döndür


132

Sorun

ASP.Net Web API Denetleyicimde bir dosya döndürmek istiyorum, ancak tüm yaklaşımlarım HttpResponseMessageJSON olarak döndürüyor.

Şimdiye kadar kod

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;
}

Tarayıcımda bu uç noktayı çağırdığımda, Web API HttpResponseMessage, HTTP İçerik Başlığı olarak ayarlanmış olarak JSON olarak döndürür application/json.

Yanıtlar:


230

Bu ASP.net-Core ise, web API sürümlerini karıştırıyorsunuz demektir. Eylemin türetilmiş bir döndürmesini IActionResultsağlayın, çünkü mevcut kodunuzda çerçeve HttpResponseMessagebir model olarak ele alınır.

[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
    }    
}

12
Benim durumumda, hafızada bir Excel oluşturmam ve onu indirmek için geri göndermem gerekiyordu, bu yüzden uzantıya sahip bir dosya adı tanımlamam gerekiyordu: return File(stream, "application/octet-stream", "filename.xlsx"); Bu şekilde, kullanıcı indirdiğinde doğrudan açabilir.
KMJungersen

NotFound()Sonuçta ne yaptığını anlıyorum , ancak .NET Core'da mı yoksa projeniz için yerel bir şey mi?
ΩmegaMan

2
@ ΩmegaMan, üzerinde yardımcı bir yöntemdir ControllerBaseve çerçevenin bir parçasıdır docs.microsoft.com/en-us/dotnet/api/…
Nkosi

3
Tamam, buldum benim benim denetleyicisi .NET Çekirdek 2.2 çalışıyordu bile, bu temel sınıftan türetilmiş değildi, konuyu Controllerbir nedenle yoktu erişimi ControllerBase.NotFound()yöntemiyle. Türetildikten sonra hepsi işe yaradı. lol / thx
ΩmegaMan

1
Sunucudan büyük dosyalar indirmeniz durumunda bu yöntem sistem belleğini tüketiyor mu? Yeni bir MemoryStream () oluşturmadığımız gerçeği göz önüne alındığında, ilk tahminim değil. Bir cevap için minnettar olurum. thx
Ehsan Najafi

18

FileResult'u şu yöntemlerle döndürebilirsiniz:

1: FileStreamResult'u döndürür

    [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: FileContentResult'u döndür

    [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
        };
    }

2
Bir içinde , bunlardan herhangi birini döndüren ControllerBasebirçok aşırı yüklenmiş ControllerBase.Fileyardımcı sürümü varsa .
Nkosi

2
Cevabınız hala geçerli. Bu yüzden cesaretiniz kırılmasın. Cevabınızı desteklemek için kullanabileceğiniz bazı kaynaklara dikkat çekiyordum.
Nkosi

1
Evet bu doğru.
Hamed Naeemaei

10

İşte bir dosya akışına ilişkin basit bir örnek:

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");
}

Not:

Kullandığınızdan emin olun FileStreamResultgelen Microsoft.AspNetCore.Mvcve değil gelen System.Web.Mvc.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.