'How to download file on browser from Dotnet core endpoint

I have a react front-end and the dotnet core web API project on the back-end. I have an endpoint on which a client can request a file using fileId from my react application. My back-end application will get the file path using a database. After that I am converting that file into a FileStream and returning a file Object from the end-point.

I am able to get a file path and converting into a stream but when I am returning a file from the endpoint but I am not getting any file download on the browser. The file extension can be any so I am using application/octet-stream as a content type.

Here is my code:

[HttpGet]
public async Task<ActionResult> GET([FromRoute] string fileId)
{
   try
   {
       string filePath = repo.getFilePath(fileId);
       FileStream fileStream = new FileStream(filePath, FileMode.Open);
       return File(fileStream, "application/octet-stream");

   }
   catch(Exception ex)
   {
       return Content(ex.Message);
   }
}


Solution 1:[1]

I have faced this issue few time ago.

I developed an endpoint on the API that takes a file from the physical directory and makes it downloadable via virtual path.

Frontend side I call a controller that does a simple redirect to the url of the virtual directory, which starts the download.

Here is my solution for .net core 5

appsettings.json

into appsetting.json define

  • Download Url

  • Virtual Directory Path

  • Physical Storage Path

    "PhysicalPath": "C:\\PhysicalPath\\",
    "VirtualPath": "/VirtualPath",
    "DownloadUrl": "https://localhost:1234",
    

Strartup.cs

Inside the Startup.cs into ConfigureServices method allow the cors:

public void ConfigureServices(IServiceCollection services)
   {
      ...
   
                services.AddCors(options =>
                {
                    options.AddPolicy(
                        name: "AllowOrigin",
                        builder => {
                            builder.AllowAnyOrigin()
                                    .AllowAnyMethod()
                                    .AllowAnyHeader();
                        });
                });
       ...
    }

at the end of Configure method define PysicalFileProvider.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
 ...
 app.UseFileServer(new FileServerOptions
 {
   FileProvider = newPhysicalFileProvider(Configuration.GetSection("PhysicalPath").Value),
                        RequestPath = new PathString(Configuration.GetSection("VirtualPath").Value),
                        EnableDirectoryBrowsing = false
  });
}

Controller

[ApiController]
public class FileController : ControllerBase
{ 
    private readonly IConfiguration _configuration;
   
    public FileController(IConfiguration configuration)
    {
        _configuration = configuration;
    }
    /// <summary>
    /// Get Phisical File .
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    [Route("{id}/{filename}")]
    public async Task<IActionResult> Get(long id, string filename)
    {
        string url = "{0}{1}/{2}";
        url = string.Format(url, _configuration.GetSection("AppUrl").Value, _configuration.GetSection("MediaStorageVirtualPath").Value, filename);

        return Redirect(url);
    }
}

if you try to call that method on swagger you recive this answer enter image description here

but if you call the method by the frontend you could downlod the file.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1