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.