ASP.NET MVC에서보기 / 다운로드로 파일 반환
데이터베이스에 저장된 파일을 ASP.NET MVC의 사용자에게 다시 보내는 데 문제가 있습니다. 내가 원하는 것은 두 개의 링크를 나열하는보기입니다. 하나는 파일을보고 브라우저로 전송 된 mimetype이 처리 방법을 결정하고 다른 하나는 강제로 다운로드하도록합니다.
호출 된 파일을 보려고 선택 SomeRandomFile.bak
하고 브라우저 에이 유형의 파일을 여는 관련 프로그램이 없으면 다운로드 동작을 기본값으로 설정하는 데 아무런 문제가 없습니다. 그러나 파일을 보도록 선택 SomeRandomFile.pdf
하거나 SomeRandomFile.jpg
파일을 열기를 원할 경우. 그러나 파일 형식에 관계없이 다운로드 프롬프트를 강제로 실행할 수 있도록 다운로드 링크를 옆으로 유지하고 싶습니다. 이게 말이 돼?
시도했지만 FileStreamResult
대부분의 파일에서 작동합니다. 생성자는 기본적으로 파일 이름을 허용하지 않으므로 알 수없는 파일에는 URL을 기반으로 파일 이름이 할당됩니다 (콘텐츠 유형을 기반으로 확장자를 알 수 없음). 파일 이름을 지정하여 파일 이름을 지정하면 브라우저에서 파일을 직접 열 수 없으며 다운로드 프롬프트가 표시됩니다. 다른 사람이 이것을 만났습니다.
이것들은 내가 지금까지 시도한 것의 예입니다.
//Gives me a download prompt.
return File(document.Data, document.ContentType, document.Name);
//Opens if it is a known extension type, downloads otherwise (download has bogus name and missing extension)
return new FileStreamResult(new MemoryStream(document.Data), document.ContentType);
//Gives me a download prompt (lose the ability to open by default if known type)
return new FileStreamResult(new MemoryStream(document.Data), document.ContentType) {FileDownloadName = document.Name};
어떤 제안?
업데이트 : 이 질문은 많은 사람들과 화음을 치는 것처럼 보이므로 업데이트를 게시 할 것이라고 생각했습니다. 국제 문자와 관련하여 Oskar가 추가 한 아래의 허용되는 답변에 대한 경고는 완전히 유효하며 ContentDisposition
수업 사용으로 인해 몇 번 명중했습니다 . 그 이후 로이 문제를 해결하기 위해 구현을 업데이트했습니다. 아래 코드는 ASP.NET Core (Full Framework) 앱 에서이 문제에 대한 가장 최근의 화신에서 얻은 것이지만 System.Net.Http.Headers.ContentDispositionHeaderValue
클래스를 사용하고 있기 때문에 이전 MVC 응용 프로그램에서 최소한의 변경으로 작동해야합니다 .
using System.Net.Http.Headers;
public IActionResult Download()
{
Document document = ... //Obtain document from database context
//"attachment" means always prompt the user to download
//"inline" means let the browser try and handle it
var cd = new ContentDispositionHeaderValue("attachment")
{
FileNameStar = document.FileName
};
Response.Headers.Add(HeaderNames.ContentDisposition, cd.ToString());
return File(document.Data, document.ContentType);
}
// an entity class for the document in my database
public class Document
{
public string FileName { get; set; }
public string ContentType { get; set; }
public byte[] Data { get; set; }
//Other properties left out for brevity
}
public ActionResult Download()
{
var document = ...
var cd = new System.Net.Mime.ContentDisposition
{
// for example foo.bak
FileName = document.FileName,
// always prompt the user for downloading, set to true if you want
// the browser to try to show the file inline
Inline = false,
};
Response.AppendHeader("Content-Disposition", cd.ToString());
return File(document.Data, document.ContentType);
}
참고 : 위의 예제 코드는 파일 이름에서 국제 문자를 올바르게 설명하지 못합니다. 관련 표준화에 대해서는 RFC6266을 참조하십시오. 나는 최신 버전의 ASP.Net MVC의 File()
메소드와 ContentDispositionHeaderValue
클래스가 이것을 올바르게 설명 한다고 생각 합니다. -오스카 2016-02-25
"document"변수에 대한 유형 힌트가 없기 때문에 허용 된 답변에 문제가있었습니다. var document = ...
그래서 다른 사람이 어려움을 겪고있는 경우 나를 대신하여 나를 위해 일한 것을 게시하고 있습니다.
public ActionResult DownloadFile()
{
string filename = "File.pdf";
string filepath = AppDomain.CurrentDomain.BaseDirectory + "/Path/To/File/" + filename;
byte[] filedata = System.IO.File.ReadAllBytes(filepath);
string contentType = MimeMapping.GetMimeMapping(filepath);
var cd = new System.Net.Mime.ContentDisposition
{
FileName = filename,
Inline = true,
};
Response.AppendHeader("Content-Disposition", cd.ToString());
return File(filedata, contentType);
}
Darin Dimitrov의 대답 은 맞습니다. 단지 추가 :
Response.AppendHeader("Content-Disposition", cd.ToString());
응답에 이미 "Content-Disposition"헤더가 포함되어 있으면 브라우저에서 파일 렌더링에 실패 할 수 있습니다. 이 경우 다음을 사용할 수 있습니다.
Response.Headers.Add("Content-Disposition", cd.ToString());
파일 을 보려면 (예 : txt) :
return File("~/TextFileInRootDir.txt", MediaTypeNames.Text.Plain);
파일 을 다운로드 하려면 (예 : txt) :
return File("~/TextFileInRootDir.txt", MediaTypeNames.Text.Plain, "TextFile.txt");
참고 : 파일을 다운로드하려면 fileDownloadName 인수를 전달해야합니다
나는이 대답이 더 깨끗하다고 생각합니다 ( https://stackoverflow.com/a/3007668/550975 기반 )
public ActionResult GetAttachment(long id)
{
FileAttachment attachment;
using (var db = new TheContext())
{
attachment = db.FileAttachments.FirstOrDefault(x => x.Id == id);
}
return File(attachment.FileData, "application/force-download", Path.GetFileName(attachment.FileName));
}
FileVirtualPath-> Research \ Global Office Review.pdf
public virtual ActionResult GetFile()
{
return File(FileVirtualPath, "application/force-download", Path.GetFileName(FileVirtualPath));
}
아래 코드는 API 서비스에서 pdf 파일을 가져 와서 브라우저에 응답하는 데 도움이되었습니다.
public async Task<FileResult> PrintPdfStatements(string fileName)
{
var fileContent = await GetFileStreamAsync(fileName);
var fileContentBytes = ((MemoryStream)fileContent).ToArray();
return File(fileContentBytes, System.Net.Mime.MediaTypeNames.Application.Pdf);
}
동작 메소드는 파일의 스트림, 바이트 [] 또는 가상 경로와 함께 FileResult를 리턴해야합니다. 또한 다운로드중인 파일의 컨텐츠 유형을 알아야합니다. 다음은 샘플 (빠른 / 더러운) 유틸리티 방법입니다. 샘플 비디오 링크 asp.net core를 사용하여 파일을 다운로드하는 방법
[Route("api/[controller]")]
public class DownloadController : Controller
{
[HttpGet]
public async Task<IActionResult> Download()
{
var path = @"C:\Vetrivel\winforms.png";
var memory = new MemoryStream();
using (var stream = new FileStream(path, FileMode.Open))
{
await stream.CopyToAsync(memory);
}
memory.Position = 0;
var ext = Path.GetExtension(path).ToLowerInvariant();
return File(memory, GetMimeTypes()[ext], Path.GetFileName(path));
}
private Dictionary<string, string> GetMimeTypes()
{
return new Dictionary<string, string>
{
{".txt", "text/plain"},
{".pdf", "application/pdf"},
{".doc", "application/vnd.ms-word"},
{".docx", "application/vnd.ms-word"},
{".png", "image/png"},
{".jpg", "image/jpeg"},
...
};
}
}
참고 URL : https://stackoverflow.com/questions/5826649/returning-a-file-to-view-download-in-asp-net-mvc
'Programing' 카테고리의 다른 글
parseInt가 Array # map으로 NaN을 생성하는 이유는 무엇입니까? (0) | 2020.03.23 |
---|---|
저장 프로 시저 란 무엇입니까? (0) | 2020.03.23 |
디렉토리에 대한 링크를 만드는 방법 (0) | 2020.03.23 |
현지 시간 문자열을 UTC로 변환하는 방법? (0) | 2020.03.23 |
Maven 저장소에서 Oracle JDBC 드라이버 찾기 (0) | 2020.03.23 |