Reputation: 23
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);
}
}
Upvotes: 1
Views: 3950
Reputation: 165
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
into appsetting.json define
Download Url
Virtual Directory Path
Physical Storage Path
"PhysicalPath": "C:\\PhysicalPath\\",
"VirtualPath": "/VirtualPath",
"DownloadUrl": "https://localhost:1234",
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
});
}
[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("VirtualPath").Value, filename);
return Redirect(url);
}
}
if you try to call that method on swagger you recive this answer
but if you call the method by the frontend you could downlod the file.
Upvotes: 2