ASP의 컨트롤러에서 이진 파일을 반환하는 중입니다.NET 웹 API
저는 ASP를 이용한 웹 서비스를 하고 있습니다.대부분 이진 파일을 제공할 NET MVC의 새로운 웹 API.cab
그리고..exe
파일
다음 컨트롤러 방법이 작동하는 것 같습니다. 즉, 파일을 반환하지만 내용 유형을 다음으로 설정합니다.application/json
:
public HttpResponseMessage<Stream> Post(string version, string environment, string filetype)
{
var path = @"C:\Temp\test.exe";
var stream = new FileStream(path, FileMode.Open);
return new HttpResponseMessage<Stream>(stream, new MediaTypeHeaderValue("application/octet-stream"));
}
이것을 하는 더 좋은 방법이 있습니까?
간단한 기능을 사용해 보십시오.Content
속성 설정:
// using System.IO;
// using System.Net.Http;
// using System.Net.Http.Headers;
public HttpResponseMessage Post(string version, string environment,
string filetype)
{
var path = @"C:\Temp\test.exe";
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
var stream = new FileStream(path, FileMode.Open, FileAccess.Read);
result.Content = new StreamContent(stream);
result.Content.Headers.ContentType =
new MediaTypeHeaderValue("application/octet-stream");
return result;
}
다음에 대해 주의해야 할 몇 가지 사항stream
사용:
전화하면 안 됩니다.
stream.Dispose()
웹 API가 컨트롤러 방법을 처리할 때 여전히 액세스할 수 있어야 하기 때문입니다.result
클라이언트에 데이터를 다시 보냅니다.따라서 다음을 사용하지 마십시오.using (var stream = …)
웹 API가 스트림을 처리합니다.스트림의 현재 위치가 0(즉, 스트림 데이터의 시작)으로 설정되어 있는지 확인합니다.위의 예에서 파일을 연 지 얼마 되지 않았기 때문에 이 값은 지정된 값입니다.그러나 다른 시나리오(예: 일부 이진 데이터를 처음 다음에 쓸 때)에서는
MemoryStream
), 다음 작업을 수행합니다.stream.Seek(0, SeekOrigin.Begin);
또는 집합stream.Position = 0;
파일 스트림을 사용하면 권한을 명시적으로 지정하면 웹 서버의 액세스 권한 문제를 방지할 수 있습니다. IIS 응용 프로그램 풀 계정에는 종종 wwwroot에 대한 읽기/목록/실행 액세스 권한만 부여됩니다.
Web API 2의 경우 다음을 구현할 수 있습니다.IHttpActionResult
내 것은 다음과 같습니다.
using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
class FileResult : IHttpActionResult
{
private readonly string _filePath;
private readonly string _contentType;
public FileResult(string filePath, string contentType = null)
{
if (filePath == null) throw new ArgumentNullException("filePath");
_filePath = filePath;
_contentType = contentType;
}
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
var response = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StreamContent(File.OpenRead(_filePath))
};
var contentType = _contentType ?? MimeMapping.GetMimeMapping(Path.GetExtension(_filePath));
response.Content.Headers.ContentType = new MediaTypeHeaderValue(contentType);
return Task.FromResult(response);
}
}
컨트롤러에 다음과 같은 기능이 있습니다.
[Route("Images/{*imagePath}")]
public IHttpActionResult GetImage(string imagePath)
{
var serverPath = Path.Combine(_rootPath, imagePath);
var fileInfo = new FileInfo(serverPath);
return !fileInfo.Exists
? (IHttpActionResult) NotFound()
: new FileResult(fileInfo.FullName);
}
IIS에 확장자가 있는 요청을 무시하여 요청이 컨트롤러에 전달되도록 할 수 있는 한 가지 방법은 다음과 같습니다.
<!-- web.config -->
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
를 사용하는 사용자용.NET 코어:
IActionResult 인터페이스를 API 컨트롤러 방식으로 사용할 수 있습니다.
[HttpGet("GetReportData/{year}")]
public async Task<IActionResult> GetReportData(int year)
{
// Render Excel document in memory and return as Byte[]
Byte[] file = await this._reportDao.RenderReportAsExcel(year);
return File(file, "application/vnd.openxmlformats", "fileName.xlsx");
}
이 예는 단순하지만 요점을 이해해야 합니다..NET Core에서는 이전 버전보다 이 프로세스가 훨씬 간단합니다.NET - 즉, 응답 유형, 내용, 헤더 등을 설정하지 않습니다.
또한 파일 및 확장명의 MIME 유형은 개별적인 필요에 따라 달라집니다.
제안된 솔루션은 잘 작동하지만 응답 스트림의 형식을 적절하게 지정하여 컨트롤러에서 바이트 배열을 반환하는 다른 방법이 있습니다.
- 요청에서 "Accept: application/octet-stream" 헤더를 설정합니다.
- 서버 측에서 이 MIME 유형을 지원할 미디어 유형 포맷터를 추가합니다.
안타깝게도 WebApi에는 "애플리케이션/옥텟 스트림"에 대한 포맷터가 포함되어 있지 않습니다.여기 GitHub: BinaryMediaTypeFormatter에 구현이 있습니다(webapi 2에서 작동하도록 하기 위한 약간의 적응이 있으며, 메서드 시그니처가 변경되었습니다).
이 포맷터를 글로벌 구성에 추가할 수 있습니다.
HttpConfiguration config;
// ...
config.Formatters.Add(new BinaryMediaTypeFormatter(false));
"WebApi"를 사용해야 .BinaryMediaTypeFormatter
요청이 올바른 Accept 헤더를 지정하는 경우.
바이트[]를 반환하는 작업 컨트롤러가 테스트하기에 더 편하기 때문에 이 솔루션을 선호합니다.그러나 다른 솔루션을 사용하면 "application/octet-stream"(예: "image/gif")이 아닌 다른 내용 유형을 반환하려는 경우 더 많은 제어를 할 수 있습니다.
승인된 답변의 메소드를 사용하여 상당히 큰 파일을 다운로드하는 동안 API가 두 번 이상 호출되는 문제가 있는 사람은 응답 버퍼링을 실제 시스템으로 설정하십시오.Web.HttpContext.현재의.대답.버퍼 = true;
이렇게 하면 전체 이진 내용이 클라이언트로 전송되기 전에 서버 측에서 버퍼링됩니다.그렇지 않으면 여러 요청이 컨트롤러로 전송되고 제대로 처리하지 않으면 파일이 손상됩니다.
사용 중인 오버로드는 일련화 형식의 열거를 설정합니다.내용 유형을 다음과 같이 명시적으로 지정해야 합니다.
httpResponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
시도해 볼 수 있습니다.
httpResponseMessage.Content.Headers.Add("Content-Type", "application/octet-stream");
다음 코드 스니펫을 시도할 수 있습니다.
httpResponseMessage.Content.Headers.Add("Content-Type", "application/octet-stream");
그것이 당신에게 효과가 있기를 바랍니다.
언급URL : https://stackoverflow.com/questions/9541351/returning-binary-file-from-controller-in-asp-net-web-api
'programing' 카테고리의 다른 글
PHP 스프레드시트로 매우 큰 스프레드시트 구축 (0) | 2023.05.06 |
---|---|
고유 사용자 ID의 시퀀스를 저장하기 위한 MongoDB의 자동 증분 (0) | 2023.05.06 |
비주얼 스튜디오에서 이클립스의 Ctrl+클릭? (0) | 2023.05.06 |
삭제 후 SQL Server에서 자동 증분 재설정 (0) | 2023.05.06 |
Excel에서 날짜 시간을 표시하는 방법 (0) | 2023.05.06 |