在ASP.NETMVC中返回要查看/下载的文件

在ASP.NETMVC中返回要查看/下载的文件

我在将存储在数据库中的文件发送回ASP.NETMVC中的用户时遇到了问题。我想要的是一个列出两个链接的视图,一个是查看文件并让发送到浏览器的mimetype决定如何处理它,另一个是强制下载。

如果我选择查看一个名为SomeRandomFile.bak而且浏览器没有一个相关的程序来打开这种类型的文件,那么我对它默认的下载行为没有问题。但是,如果我选择查看一个名为SomeRandomFile.pdfSomeRandomFile.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.NETCore(完整框架)应用程序中出现的这个问题的代码,但它也应该在旧的MVC应用程序中进行最小的更改,因为我使用的是System.Net.Http.Headers.ContentDispositionHeaderValue班级,等级。

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}


阿波罗的战车
浏览 1322回答 3
3回答

幕布斯6054654

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);}注:上面的示例代码无法正确解释文件名中的国际字符。有关标准,见RFC 6266。我相信ASP.NETMVC的最新版本File()方法和ContentDispositionHeaderValue类正确地说明了这一点。

慕无忌1623718

只是一个补充:Response.AppendHeader("Content-Disposition", cd.ToString());如果您的响应已经包含“内容处理”标题,则可能导致浏览器无法呈现文件。在这种情况下,您可能需要使用:Response.Headers.Add("Content-Disposition", cd.ToString());
打开App,查看更多内容
随时随地看视频慕课网APP