也许我不理解VirtualFileResult是什么,但我不确定为什么文件存在时会抛出FileNotFoundException。这是代码:
if (System.IO.File.Exists(fileName))
{
FileInfo info = new FileInfo(fileName);
return File(fileName, FileUtility.GetContentType(fileName), info.Name);
}
(编辑:FileUtility.GetContentType
(正确)返回文件的Mime类型,在我的情况下是"application/pdf"
。)
以下是我得到的异常:(我删除了文件路径)
System.IO.FileNotFoundException: Could not find file: [file path removed]
File name: '[file path removed]'
at Microsoft.AspNet.Mvc.VirtualFileResult.<WriteFileAsync>d__11.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at Microsoft.AspNet.Mvc.Controllers.FilterActionInvoker.<InvokeResultAsync>d__56.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at Microsoft.AspNet.Mvc.Controllers.FilterActionInvoker.<InvokeResultFilterAsync>d__55.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.AspNet.Mvc.Controllers.FilterActionInvoker.<InvokeAllResultFiltersAsync>d__54.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at Microsoft.AspNet.Mvc.Controllers.FilterActionInvoker.<InvokeResourceFilterAsync>d__49.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.AspNet.Mvc.Controllers.FilterActionInvoker.<InvokeAsync>d__44.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at Microsoft.AspNet.Mvc.Infrastructure.MvcRouteHandler.<RouteAsync>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at Microsoft.AspNet.Routing.Template.TemplateRoute.<RouteAsync>d__27.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at Microsoft.AspNet.Routing.RouteCollection.<RouteAsync>d__9.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at Microsoft.AspNet.Builder.RouterMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at Microsoft.AspNet.IISPlatformHandler.IISPlatformHandlerMiddleware.<Invoke>d__8.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at Microsoft.AspNet.Diagnostics.StatusCodePagesMiddleware.<Invoke>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at Microsoft.AspNet.Diagnostics.DeveloperExceptionPageMiddleware.<Invoke>d__7.MoveNext()
即使对文件是否存在进行了明确的检查,它似乎也在喋喋不休。我也可以手动确认文件存在。
也许我不理解VirtualFileResult是什么(File方法返回此)。在文档here上,它并没有真正描述它是什么。
我正在使用ASP.NET 5 RC1。
答案 0 :(得分:3)
VirtualFileResult
类需要在其构造函数中指向文件的虚拟路径
这意味着您需要提供相对于wwwroot
文件夹的路径,因为它使用HostingEnvironment&#39; WebRootFileProvider
。
private IFileProvider GetFileProvider(IServiceProvider requestServices)
{
if (FileProvider != null)
{
return FileProvider;
}
var hostingEnvironment = requestServices.GetService<IHostingEnvironment>();
FileProvider = hostingEnvironment.WebRootFileProvider;
return FileProvider;
}
}
检查github
上的代码答案 1 :(得分:2)
运气不好(&#34; index.html&#34;)或文件(&#34;〜/ index.html&#34;),Virtualfileresult会抛出NotFound。
我的解决方案是使用Microsoft.AspNetCore.Mvc.ControllerBase 方法File(Stream fileStream ...):
public virtual FileStreamResult File(Stream fileStream,
string contentType, string fileDownloadName);
索引控制器示例:
using System.IO;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
public class IndexController : Controller
{
ILoggerFactory Logger;
public IndexController(ILoggerFactory loggerFactory)
{
Logger = loggerFactory;
}
static string sep = Path.DirectorySeparatorChar.ToString();
[HttpGet("/index")]
[HttpGet("/")]
public IActionResult Index()
{
var log = Logger.CreateLogger("trace");
var path = $"{Startup.RootPath}{sep}index.html";
log.LogWarning(path);
Stream fileStream = new System.IO.FileStream(path, FileMode.Open);
return File(fileStream, "text/html");
}
}
// AspnetCore version 1.1.1 :
// <TargetFramework>netcoreapp1.1</TargetFramework>
// <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="1.1.1" />
答案 2 :(得分:1)
您要查找的方法是PhysicalFile()
:
return PhysicalFile(fileName, FileUtility.GetContentType(fileName), info.Name);
当心,请勿为此使用呼叫者提供的路径。
答案 3 :(得分:0)
您的VirtualFileResult必须是应用程序的wwwroot 的相对路径。
return File("~/foo.js","text/javascript")
将指向wwwroot / foo.js