File Downloads in a .NET Web Application Using Web API

In this guide, we'll walk you through implementing file downloads in a .NET Web API project, covering scenarios such as normal file downloads and zipped file downloads.

Getting Started

Ensure you have a .NET Web API project set up. If not, create a new project or use an existing one.

Normal File Download

Let's start with a simple file download scenario. Consider a controller method that retrieves a text file containing a "Hello, World!" message and returns it as part of the HTTP response.

[ApiController]
[Route("[controller]")]
public class DownloadController : ControllerBase
{
        private readonly ILogger<DownloadController> _logger;

        public DownloadController(ILogger<DownloadController> logger)
        {
            _logger = logger;
        }


        [HttpGet]
        [Route("text")]
        public FileContentResult DownloadTextFile()
        {
            string helloWorldText = "Hello, World!";
            byte[] textFileBytes = Encoding.UTF8.GetBytes(helloWorldText);

            return File(textFileBytes, "text/plain", "Helloworld.txt");
        }

}

Notice, how the return type of this action is FileContentResult . We can call this endpoint using the url https://localhost:7058/download/text

Zipped File Download

For scenarios where multiple files need to be provided in a single download, consider zipping them before sending them to the client.

        [HttpGet]
        [Route("zip")]
        public FileContentResult DownloadZippedFiles()
        {
            Dictionary<string, byte[]> files = GetMultipleFiles();

            using (var memoryStream = new MemoryStream())
            {
                using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
                {
                    foreach (var file in files)
                    {
                        var entry = archive.CreateEntry(file.Key);
                        using (var entryStream = entry.Open())
                        {
                            entryStream.Write(file.Value, 0, file.Value.Length);
                        }
                    }
                }
                return File(memoryStream.ToArray(), "application/zip", "files.zip");
            }
        }

        private Dictionary<string, byte[]> GetMultipleFiles()
        {
            Dictionary<string, byte[]> files = new Dictionary<string, byte[]>();

            // Add a sample text file
            files.Add("sample_text.txt", GetFileBytes("sample_files/HelloWorld.txt"));

            // Add a sample Word document
            files.Add("sample_word.docx", GetFileBytes("sample_files/HelloWorld.docx"));

            // Add a sample PDF file
            files.Add("sample_pdf.pdf", GetFileBytes("sample_files/HelloWorld.pdf"));

            return files;
        }

        private byte[] GetFileBytes(string filePath)
        {
            // Read the file content and return as byte array
            if (System.IO.File.Exists(filePath))
            {
                return System.IO.File.ReadAllBytes(filePath);
            }

            // If the file doesn't exist, return an empty byte array or handle accordingly
            return new byte[0];
        }

Ensure you adapt the GetMultipleFiles() method to retrieve the files you want to include in the zip archive. I have included the sample files in the project itself for now, as you can see below: