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

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

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

有人知道在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;
}

当前回答

如果你使用的是。net Framework 4.5,那么你需要使用MimeMapping。GetMimeMapping(string FileName)获取文件的mime类型。这就是我在行动中使用它的方式。

return File(Path.Combine(@"c:\path", fileFromDB.FileNameOnDisk), MimeMapping.GetMimeMapping(fileFromDB.FileName), fileFromDB.FileName);

其他回答

如果你使用的是。net Framework 4.5,那么你需要使用MimeMapping。GetMimeMapping(string 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);
    }
}

它很简单,只要给你的物理路径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);
        }

感谢伊恩·亨利!

如果你需要从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是MyFiles表中的varbinary(MAX)。