ASP.Net Core Web API의 반환 파일


131

문제

ASP.Net Web API Controller에서 파일을 반환하고 싶지만 모든 접근 방식 HttpResponseMessage은 JSON으로 반환합니다 .

지금까지 코드

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

브라우저에서이 끝점을 호출하면 Web API는 HttpResponseMessageHTTP 콘텐츠 헤더가 application/json.

답변:


229

이것이 ASP.net-Core이면 웹 API 버전을 혼합하는 것입니다. IActionResult현재 코드에서 프레임 워크가 HttpResponseMessage모델로 취급되기 때문에 액션이 파생을 반환하도록 합니다 .

[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
필자의 경우에는 Excel을 메모리에 렌더링하고 다운로드를 위해 반환해야했기 때문에 확장명이있는 파일 이름도 정의해야했습니다. return File(stream, "application/octet-stream", "filename.xlsx"); 이렇게하면 다운로드 할 때 사용자가 직접 열 수 있습니다.
KMJungersen

NotFound()궁극적으로 무엇을하는지 이해 하지만 .NET Core에 상주합니까 아니면 프로젝트에 로컬입니까?
ΩmegaMan

2
@ ΩmegaMan은 도우미 메서드 ControllerBase이며 프레임 워크 자체의 일부입니다. docs.microsoft.com/en-us/dotnet/api/…
Nkosi

3
좋아, 찾아 내 컨트롤러는 .NET 코어 2.2에서 일하고 있지만, 그것은 기본 클래스에서 파생되지 않은, 문제를 Controller에 따라서하지 않은 접근 ControllerBase.NotFound()방법을. 일단 파생되면 모든 것이 작동했습니다. lol / thx
ΩmegaMan

1
이 방법은 서버에서 대용량 파일을 다운로드하는 경우 시스템 메모리를 사용합니까? 내 첫 번째 추측은 우리가 새로운 MemoryStream ()을 만들지 않는다는 사실을 감안할 때 그렇지 않습니다. 대답 해 주시면 감사하겠습니다. thx
Ehsan Najafi

16

다음 메서드를 사용하여 FileResult를 반환 할 수 있습니다.

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

2
안에 있다면 그중 하나를 반환하는 ControllerBase많은 오버로드 된 버전의 ControllerBase.File도우미가 있습니다.
Nkosi

2
귀하의 답변은 여전히 ​​유효합니다. 그러니 낙담하지 마십시오. 귀하의 답변을 뒷받침하는 데 사용할 수있는 몇 가지 리소스를 지적했습니다.
Nkosi

1
그래 이건 사실이야.
Hamed Naeemaei

10

다음은 파일 스트리밍의 간단한 예입니다.

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

노트 :

사용하십시오 FileStreamResult에서 Microsoft.AspNetCore.Mvc하지 에서 System.Web.Mvc.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.