How to download a file in ASP.NET Core

后端 未结 9 1964
离开以前
离开以前 2020-12-02 13:14

In MVC, we have used following code to download a file. In ASP.NET core, how to achieve this?

HttpResponse response = HttpContext.Current.Response;                   


        
相关标签:
9条回答
  • 2020-12-02 13:23
        [HttpGet]
        public async Task<FileStreamResult> Download(string url, string name, string contentType)
        {
            var stream = await new HttpClient().GetStreamAsync(url);
    
            return new FileStreamResult(stream, contentType)
            {
                FileDownloadName = name,
            };
        }
    
    0 讨论(0)
  • 2020-12-02 13:28

    Action method needs to return FileResult with either a stream, byte[], or virtual path of the file. You will also need to know the content-type of the file being downloaded. Here is a sample (quick/dirty) utility method. Sample video link How to download files using asp.net core

    [Route("api/[controller]")]
    public class DownloadController : Controller
    {
        [HttpGet]
        public async Task<IActionResult> Download()
        {
            var path = @"C:\Vetrivel\winforms.png";
            var memory = new MemoryStream();
            using (var stream = new FileStream(path, FileMode.Open))
            {
                await stream.CopyToAsync(memory);
            }
            memory.Position = 0;
            var ext = Path.GetExtension(path).ToLowerInvariant();
            return File(memory, GetMimeTypes()[ext], Path.GetFileName(path));
        }
    
        private Dictionary<string, string> GetMimeTypes()
        {
            return new Dictionary<string, string>
            {
                {".txt", "text/plain"},
                {".pdf", "application/pdf"},
                {".doc", "application/vnd.ms-word"},
                {".docx", "application/vnd.ms-word"},
                {".png", "image/png"},
                {".jpg", "image/jpeg"},
                ...
            };
        }
    }
    
    0 讨论(0)
  • 2020-12-02 13:32

    Create a Service say FileService.

    public class FileService
    {
        private readonly IHostingEnvironment _hostingEnvironment;
        constructor(IHostingEnvironment hostingEnvironment)
        {
            this._hostingEnvironment = hostingEnvironment;
        }
    }
    

    Add a method to FileService MimeType of the file

    private string GetMimeType(string fileName)
    {
        // Make Sure Microsoft.AspNetCore.StaticFiles Nuget Package is installed
        var provider = new FileExtensionContentTypeProvider();
        string contentType;
        if (!provider.TryGetContentType(fileName, out contentType))
        {
            contentType = "application/octet-stream";
        }
        return contentType;
    }
    

    Now add a method to download File,

    public FileContentResult GetFile(string filename) 
    {
        var filepath = Path.Combine($"{this._environment.WebRootPath}\\path-to-required-folder\\{filename}");
    
        var mimeType = this.GetMimeType(filename); 
    
        byte[] fileBytes;
    
        if (File.Exists(filepath))
        {
            fileBytes = File.ReadAllBytes(filepath); 
        } 
        else
        {
            // Code to handle if file is not present
        }
    
        return new FileContentResult(fileBytes, mimeType)
        {
            FileDownloadName = filename
        };
    }
    

    Now add controller method and call GetFile method in FileService,

     public IActionResult DownloadFile(string filename) 
     {
        // call GetFile Method in service and return       
     }
    
    0 讨论(0)
  • 2020-12-02 13:33

    Example for Asp.net Core 2.1+ (Best practice)

    Startup.cs:

    private readonly IHostingEnvironment _env;
    
    public Startup(IConfiguration configuration, IHostingEnvironment env)
    {
        Configuration = configuration;
        _env = env;
    }
    
    services.AddSingleton(_env.ContentRootFileProvider); //Inject IFileProvider
    

    SomeService.cs:

    private readonly IFileProvider _fileProvider;
    
    public SomeService(IFileProvider fileProvider)
    {
        _fileProvider = fileProvider;
    }
    
    public FileStreamResult GetFileAsStream()
    {
        var stream = _fileProvider
            .GetFileInfo("RELATIVE PATH TO FILE FROM APP ROOT")
            .CreateReadStream();
    
        return new FileStreamResult(stream, "CONTENT-TYPE")
    }
    

    Controller will return IActionResult

    [HttpGet]
    public IActionResult Get()
    {
        return _someService.GetFileAsStream() ?? (IActionResult)NotFound();
    }
    
    0 讨论(0)
  • 2020-12-02 13:34

    You can try below code to download the file. It should return the FileResult

    public ActionResult DownloadDocument()
    {
    string filePath = "your file path";
    string fileName = ""your file name;
    
    byte[] fileBytes = System.IO.File.ReadAllBytes(filePath);
    
    return File(fileBytes, "application/force-download", fileName);
    
    }
    
    0 讨论(0)
  • 2020-12-02 13:41

    Here is my Medium article, describing everything step by step (it also includes a GitHub repo): https://medium.com/@tsafadi/download-a-file-with-asp-net-core-e23e8b198f74

    Any ways this is how the controller should look like:

    [HttpGet]
    public IActionResult DownloadFile()
    {
        // Since this is just and example, I am using a local file located inside wwwroot
        // Afterwards file is converted into a stream
        var path = Path.Combine(_hostingEnvironment.WebRootPath, "Sample.xlsx");
        var fs = new FileStream(path, FileMode.Open);
    
        // Return the file. A byte array can also be used instead of a stream
        return File(fs, "application/octet-stream", "Sample.xlsx");
    }
    

    Inside the view:

    $("button").click(function () {
        var xhr = new XMLHttpRequest();
        xhr.open("GET", "Download/DownloadFile", true);
        xhr.responseType = "blob";
        xhr.onload = function (e) {
            if (this.status == 200) {
                var blob = this.response;
    
                /* Get filename from Content-Disposition header */
                var filename = "";
                var disposition = xhr.getResponseHeader('Content-Disposition');
                if (disposition && disposition.indexOf('attachment') !== -1) {
                    var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
                    var matches = filenameRegex.exec(disposition);
                    if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, '');
                }
    
                // This does the trick
                var a = document.createElement('a');
                a.href = window.URL.createObjectURL(blob);
                a.download = filename;
                a.dispatchEvent(new MouseEvent('click'));
            }
        }
        xhr.send();
    });
    
    0 讨论(0)
提交回复
热议问题