简体   繁体   中英

Download File C# MVC from byte[]

I am attempting to download a file from a byte array, but the prompt does not appear to do the download. Do I need include additional ContentDisposition attributes? If I look at the network traffic in IE I can see the file request is valid and that it's returning a 200, in addition I can also download the file from IE Debug tools content.

The file stored in the byte array is a Word document. I've set the mime type as:

application/vnd.openxmlformats-officedocument.wordprocessingml.document

And the document file name is: QuickStartGuide.docx

And ideas why the download prompt is not showing up?

[HttpPost]
[ValidateAntiForgeryToken]
public FileContentResult DocumentDownload(int documentId)
{
    try
    {
        var document = BusinessLayer.GetDocumentsByDocument(documentId, AuthenticationHandler.HostProtocol).FirstOrDefault();

        System.Net.Mime.ContentDisposition contentDisposition = new System.Net.Mime.ContentDisposition();

        contentDisposition.FileName = document.FileName;
        contentDisposition.Inline = false;

        var result = new FileContentResultWithContentDisposition(document.FileBytes, document.FileType, contentDisposition);

        return result;
    }
    catch
    {
        throw;
    }
}


public class FileContentResultWithContentDisposition : FileContentResult
{
    private const string ContentDispositionHeaderName = "Content-Disposition";

    public FileContentResultWithContentDisposition(byte[] fileContents, string contentType, ContentDisposition contentDisposition)
        : base(fileContents, contentType)
    {
        // check for null or invalid ctor arguments
        ContentDisposition = contentDisposition;
    }

    public ContentDisposition ContentDisposition { get; private set; }

    public override void ExecuteResult(ControllerContext context)
    {
        // check for null or invalid method argument
        ContentDisposition.FileName = ContentDisposition.FileName ?? FileDownloadName;
        var response = context.HttpContext.Response;
        response.ContentType = ContentType;
        response.AddHeader(ContentDispositionHeaderName, ContentDisposition.ToString());
        WriteFile(response);
    }
}

Your action method is decorated as POST , but the file download has a GET operation and the anti-forgery validation is not needed for downloads, too.

The ASP.NET MVC framework has got the built in FileResult . The MVC Controller itself has got the convenience function File(...) ( https://msdn.microsoft.com/en-us/library/system.web.mvc.controller.file(v=vs.118).aspx )

In order signal the browser to download the file, you have to specify the content type and the download filename. This will shorten your code to:

[HttpGet]
public FileResult DocumentDownload(int documentId)
{
    var document = BusinessLayer.GetDocumentsByDocument(documentId, AuthenticationHandler.HostProtocol).FirstOrDefault();

    return File(document.FileBytes, document.FileType, document.FileName);           
}

FileResult would probably suit you more. Specify your content-type and file name and I think that would be enough.

public FileResult Download()
{
    var document = BusinessLayer.GetDocumentsByDocument(documentId, AuthenticationHandler.HostProtocol).FirstOrDefault();
    string fileName = document.FileName;
    return File(document.FileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, fileName);
}

I used a generic application-octet mediatype, you can definitely use your own.

For more ways to solve your problem, please have a look at here and here

尝试将“application/force-download”添加为“content-type”标头的值,如下所述: https : //stackoverflow.com/a/3007668/5592113

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM