Download File C# MVC from byte[]

17,396

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);           
}
Share:
17,396

Related videos on Youtube

2ndAmenNot2BInfringed
Author by

2ndAmenNot2BInfringed

Updated on September 15, 2022

Comments

  • 2ndAmenNot2BInfringed
    2ndAmenNot2BInfringed over 1 year

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