Returning a file to View/Download in ASP.NET MVC

I'm encountering a problem sending files stored in a database back to the user in ASP.NET MVC. What I want is a view listing two links, one to view the file and let the mimetype sent to the browser determine how it should be handled, and the other to force a download.

If I choose to view a file called SomeRandomFile.bak and the browser doesn't have an associated program to open files of this type, then I have no problem with it defaulting to the download behavior. However, if I choose to view a file called SomeRandomFile.pdf or SomeRandomFile.jpg I want the file to simply open. But I also want to keep a download link off to the side so that I can force a download prompt regardless of the file type. Does this make sense?

I have tried FileStreamResult and it works for most files, it's constructor doesn't accept a filename by default, so unknown files are assigned the a file name based on the url (which does not know the extension to give based on content type). If I force the file name by specifying it, I lose the ability for the browser to open the file directly and I get a download prompt. Has anyone else encountered this.

These are the examples of what I've tried so far.

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

Any suggestions?


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

NOTE: This example code above fails to properly account for international characters in the filename. See RFC6266 for the relevant standardization. I believe recent versions of ASP.Net MVC's File() method and the ContentDispositionHeaderValue class properly accounts for this. - Oskar 2016-02-25


由于在“文档”变量中没有类型暗示,我无法接受所接受的答案: 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's answer is correct. Just an addition:

Response.AppendHeader("Content-Disposition", cd.ToString()); may cause the browser to fail rendering the file if your response already contains a "Content-Disposition" header. In that case, you may want to use:

Response.Headers.Add("Content-Disposition", cd.ToString());
链接地址: http://www.djcxy.com/p/20544.html

上一篇: 从Web Api控制器返回http状态码

下一篇: 在ASP.NET MVC中将文件返回到View / Download