Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

asp net core - file download results is FileNotFoundException

I'm trying to do a simple file download, but it results with FileNotFoundException.

The code in the controller:

public FileResult DownloadFile()
{
    var fileName = "1.pdf";
    var filePath = env.WebRootPath + "\\" + fileName;
    var fileExists = System.IO.File.Exists(filePath);
    return File(filePath, "application/pdf", fileName);
}

(Debugging the variable fileExists shows that it's set to true.)

The code in the view:

@Html.ActionLink("Download", "DownloadFile")

Messages from the log:

2017-03-12 09:28:45 [INF] Executing action method "Team.Controllers.ModulesExController.DownloadFile (Team)" with arguments (null) - ModelState is Valid
2017-03-12 09:28:45 [DBG] Executed action method "Team.Controllers.ModulesExController.DownloadFile (Team)", returned result "Microsoft.AspNetCore.Mvc.VirtualFileResult".
2017-03-12 09:28:45 [INF] Executing FileResult, sending file as "1.pdf"
2017-03-12 09:28:45 [INF] Executed action "Team.Controllers.ModulesExController.DownloadFile (Team)" in 0.8238ms
2017-03-12 09:28:45 [DBG] System.IO.FileNotFoundException occurred, checking if Entity Framework recorded this exception as resulting from a failed database operation.
2017-03-12 09:28:45 [DBG] Entity Framework did not record any exceptions due to failed database operations. This means the current exception is not a failed Entity Framework database operation, or the current exception occurred from a DbContext that was not obtained from request services.
2017-03-12 09:28:45 [ERR] An unhandled exception has occurred while executing the request
System.IO.FileNotFoundException: Could not find file: D:\Projekti\Team\src\Team\wwwroot\1.pdf

If I paste the link in the error message in the browser, I can open the file.

like image 321
Marko Avatar asked Mar 12 '17 08:03

Marko


2 Answers

In ASP.NET Core 2.0 you can use a PhysicalFile as the return type if you have a file path.

    public FileResult DownloadFile() {
        var fileName = "1.pdf";
        var filePath = env.WebRootPath + "\\" + fileName;
        var fileExists = System.IO.File.Exists(filePath);
        return PhysicalFile(filePath, "application/pdf", fileName);
    }
like image 75
Brad Patton Avatar answered Oct 19 '22 14:10

Brad Patton


Controller.File() is expecting a virtual path, not an absolute path.

See https://docs.microsoft.com/en-us/aspnet/core/api/microsoft.aspnetcore.mvc.controllerbase#Microsoft_AspNetCore_Mvc_ControllerBase_File_System_String_System_String_System_String_

If you want to use an absolute path, pass in a stream:

public FileResult DownloadFile()
{
    var fileName = "1.pdf";
    var filePath = env.WebRootPath + "\\" + fileName;
    var fileExists = System.IO.File.Exists(filePath);
    var fs = System.IO.File.OpenRead(filePath);
    return File(fs, "application/pdf", fileName);
}
like image 42
christofr Avatar answered Oct 19 '22 15:10

christofr