C# ASP.NET - How to download a file from an endpoint, with PDF, JPG and CSV example

I have previously written a post on how to return HTML from an ASP.NET controller endpoint. In this post I will take a more general approach on how to return different types of files such as JPG, PDF or CSV.

Downloading files using FileStreamResult

We will start by making a standard ASP.NET project and create a simple FileController and a folder called "Content" which will contain our files:

download-file-in-aspnet-controller

For this example we define four files: a csv, html, jpg and pdf file, they are placed within the "Content" folder in the project. Using the FileStreamResult class we can return and download these files. Below is an example of this:

[HttpGet("/GetFile/{filename}")]
public FileStreamResult GetFile([FromRoute]string filename)
{
    var physicalPath = $"./Content/{filename}";
    var pdfBytes = System.IO.File.ReadAllBytes(physicalPath);
    var ms = new MemoryStream(pdfBytes);
    return new FileStreamResult(ms, GetMimeType(filename));
}

We define an endpoint with the URL template /GetFile/{filename} where the filename is the name (with extension) of the file we want to download. We then read the bytes from the file and add the bytes to a memorystream so that we may stream them. NOTE: I am fetching these files from my drive, make sure that you do not introduce a vulnerability by allowing users to download files they should not. I have made it this way to make a simple example.

We deduce the MIME type of the file using a GetMimeType method:

private string GetMimeType(string filename)
{
    var extension = filename.Split(".").Last();
    switch (extension)
    {
        case "jpg":
        case "jpeg":
            return "image/jpeg";
        case "csv":
            return "text/csv";
        case "pdf":
            return "application/pdf";
        case "html":
            return "text/html";
        default:
            throw new ArgumentException($"Unsupported file type, file: {filename}");
    }
}

In the above we get the MIME type based on the extension of the file we are to download. That is all there is to it, we can now return the bytes along with the MIME type as a FileStreamResult.

When calling https://localhost:7102/GetFile/somejpg.jpg in Swagger we will see the following:

download-image-using-filestreamresult-swagger

As you can see it shows an image as the response body. The complete FileController class can be seen below:

using Microsoft.AspNetCore.Mvc;

namespace WebApplication4.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class FileController : ControllerBase
    {

        [HttpGet("/GetFile/{filename}")]
        public FileStreamResult GetFile([FromRoute]string filename)
        {
            var physicalPath = $"./Content/{filename}";
            var pdfBytes = System.IO.File.ReadAllBytes(physicalPath);
            var ms = new MemoryStream(pdfBytes);
            return new FileStreamResult(ms, GetMimeType(filename));
        }

        private string GetMimeType(string filename)
        {
            var extension = filename.Split(".").Last();
            switch (extension)
            {
                case "jpg":
                case "jpeg":
                    return "image/jpeg";
                case "csv":
                    return "text/csv";
                case "pdf":
                    return "application/pdf";
                case "html":
                    return "text/html";
                default:
                    throw new ArgumentException($"Unsupported file type, file: {filename}");
            }
        }
    }
}

That is all

I hope you found this helpful, feel free to leave a comment down below! I read all of them.