下载任何类型的Asp文件。Net MVC使用FileResult?

我有它建议我应该使用FileResult允许用户从我的Asp下载文件。Net MVC应用程序。但我能找到的唯一例子总是与图像文件有关(指定内容类型image/jpeg)。

但如果我不知道文件类型怎么办?我希望用户能够从我的网站的文件区下载几乎任何文件。

我读过一个这样做的方法(代码参见以前的文章),实际上工作正常,除了一件事:在另存为对话框中出现的文件名与文件路径用下划线连接(folder_folder_file.ext)。此外,似乎人们认为我应该返回一个FileResult,而不是使用这个自定义类,我已经找到BinaryContentResult。

有人知道在MVC中做这样的下载的“正确”方式吗?

< p >编辑: 我得到了答案(如下),但只是认为我应该张贴完整的工作代码,如果其他人感兴趣:

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;
}
505825 次浏览

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

你可以指定通用的八字节流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);

GetFile应该关闭文件(或者在using中打开它)。然后,您可以在转换为字节后删除文件——下载将在字节缓冲区上完成。

    byte[] GetFile(string s)
{
byte[] data;
using (System.IO.FileStream fs = System.IO.File.OpenRead(s))
{
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;
}

在下载方法中。

        byte[] fileBytes = GetFile(file);
// delete the file after conversion to bytes
System.IO.File.Delete(file);
// have the file download dialog only display the base name of the file            return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, Path.GetFileName(file));

感谢伊恩•亨利!

如果你需要从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模型,而myfile在数据库中表示表格FileDatamyfile表中的varbinary(MAX)

它很简单,只要给你的物理路径directoryPath与文件名

public FilePathResult GetFileFromDisk(string fileName)
{
return File(directoryPath, "multipart/form-data", fileName);
}
< p >如果(string.IsNullOrWhiteSpace(文件名)

. return Content("filename not present")
        var path = Path.Combine(your path, your filename);


var stream = new FileStream(path, FileMode.Open);


return File(stream, System.Net.Mime.MediaTypeNames.Application.Octet, 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);
}