사용자가 내 Asp.Net MVC 응용 프로그램에서 파일을 다운로드 할 수 있도록 FileResult를 사용해야한다고 제안했습니다. 그러나 내가 찾을 수있는 유일한 예는 항상 이미지 파일 (콘텐츠 유형 이미지 / JPEG 지정)과 관련이 있습니다.
그러나 파일 형식을 알 수 없으면 어떻게합니까? 사용자가 내 사이트의 파일 영역에서 거의 모든 파일을 다운로드 할 수 있기를 바랍니다.
이 작업을 수행하는 한 가지 방법 ( 이전 코드 참조)을 읽었 지만 실제로는 한 가지 경우를 제외하고는 잘 작동합니다. 다른 이름으로 저장 대화 상자에 나타나는 파일 이름은 파일 경로에서 밑줄로 연결됩니다 ( folder_folder_file.ext). 또한 사람들은 BinaryContentResult를 찾은이 사용자 정의 클래스를 사용하는 대신 FileResult를 반환해야한다고 생각합니다.
MVC에서 이러한 다운로드를 수행하는 “올바른”방법을 아는 사람이 있습니까?
편집 : 나는 대답을 얻었지만 (다른 사람이 관심이 있다면 전체 작업 코드를 게시해야한다고 생각했습니다.
public ActionResult Download(string filePath, string fileName)
{
string fullName = Path.Combine(GetBaseDir(), filePath, fileName);
byte[] fileBytes = GetFile(fullName);
return File(
fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, fileName);
}
byte[] GetFile(string s)
{
System.IO.FileStream fs = System.IO.File.OpenRead(s);
byte[] data = new byte[fs.Length];
int br = fs.Read(data, 0, data.Length);
if (br != fs.Length)
throw new System.IO.IOException(s);
return data;
}
답변
일반적인 옥텟 스트림 MIME 유형을 지정할 수 있습니다.
public FileResult Download()
{
byte[] fileBytes = System.IO.File.ReadAllBytes(@"c:\folder\myfile.ext");
string fileName = "myfile.ext";
return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, fileName);
}
답변
MVC 프레임 워크는이를 기본적으로 지원합니다. System.Web.MVC.Controller.File의 제어기에 의해 파일을 반환하는 방법을 제공 이름 / 스트림 / 어레이 .
예를 들어 파일의 가상 경로를 사용하면 다음을 수행 할 수 있습니다.
return File(virtualFilePath, System.Net.Mime.MediaTypeNames.Application.Octet, Path.GetFileName(virtualFilePath));
답변
.NET Framework 4.5를 사용하는 경우 MimeMapping.GetMimeMapping (문자열 FileName)을 사용하여 파일의 MIME 유형을 가져옵니다. 이것이 내가 행동에 사용한 방법입니다.
return File(Path.Combine(@"c:\path", fileFromDB.FileNameOnDisk), MimeMapping.GetMimeMapping(fileFromDB.FileName), fileFromDB.FileName);
답변
Phil Haack은 커스텀 파일 다운로드 액션 결과 클래스를 생성 한 훌륭한 기사를 가지고 있습니다. 파일의 가상 경로와 저장할 이름 만 지정하면됩니다.
나는 그것을 한 번 사용했고 여기에 내 코드가 있습니다.
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Download(int fileID)
{
Data.LinqToSql.File file = _fileService.GetByID(fileID);
return new DownloadResult { VirtualPath = GetVirtualPath(file.Path),
FileDownloadName = file.Name };
}
내 예제에서 나는 파일의 물리적 경로를 저장하고 있었기 때문에이 도우미 방법을 사용하여 가상 경로로 변환 할 수없는 곳을 찾았습니다.
private string GetVirtualPath(string physicalPath)
{
string rootpath = Server.MapPath("~/");
physicalPath = physicalPath.Replace(rootpath, "");
physicalPath = physicalPath.Replace("\\", "/");
return "~/" + physicalPath;
}
Phill Haack의 기사에서 가져온 전체 클래스는 다음과 같습니다.
public class DownloadResult : ActionResult {
public DownloadResult() {}
public DownloadResult(string virtualPath) {
this.VirtualPath = virtualPath;
}
public string VirtualPath {
get;
set;
}
public string FileDownloadName {
get;
set;
}
public override void ExecuteResult(ControllerContext context) {
if (!String.IsNullOrEmpty(FileDownloadName)) {
context.HttpContext.Response.AddHeader("content-disposition",
"attachment; filename=" + this.FileDownloadName)
}
string filePath = context.HttpContext.Server.MapPath(this.VirtualPath);
context.HttpContext.Response.TransmitFile(filePath);
}
}
답변
이안 헨리 감사합니다 !
MS SQL Server에서 파일을 가져와야 할 경우 여기에 해결책이 있습니다.
public FileResult DownloadDocument(string id)
{
if (!string.IsNullOrEmpty(id))
{
try
{
var fileId = Guid.Parse(id);
var myFile = AppModel.MyFiles.SingleOrDefault(x => x.Id == fileId);
if (myFile != null)
{
byte[] fileBytes = myFile.FileData;
return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, myFile.FileName);
}
}
catch
{
}
}
return null;
}
어디 AppModel이는 것입니다 EntityFramework
모델과 MyFiles 선물의 테이블 데이터베이스에.
FILEDATA은 이다 varbinary(MAX)
에 MyFiles의 테이블.
답변
그것의 간단한 파일 이름으로 directoryPath에 실제 경로를 제공하십시오.
public FilePathResult GetFileFromDisk(string fileName)
{
return File(directoryPath, "multipart/form-data", fileName);
}
답변
public ActionResult Download()
{
var document = //Obtain document from database context
var cd = new System.Net.Mime.ContentDisposition
{
FileName = document.FileName,
Inline = false,
};
Response.AppendHeader("Content-Disposition", cd.ToString());
return File(document.Data, document.ContentType);
}