[英]Asp.Net Core 2.0-2.2 Kestrel not serving static content
使用 IIS express 运行 Asp.Net Core 2.0(或 2.2)应用程序时,静态文件(css、js)按预期提供。 但是,当通过“dotnet publish -o [targetDirectory]”和 dotnet [website.dll] 使用命令行/Kestrel 时,Kestrel 不提供任何静态内容。 使用浏览器 F12,我看到 Kestrel 返回 404 错误。 仔细一看,在浏览器中直接输入文件路径(localhost:5000/ css /cssfile.css)时,文件没有显示,但浏览器似乎重定向到“localhost:5000/cssfile.css”,但仍然返回404错误(注意缺少的 /css/ 目录)。
我通过 Visual Studio 2017 创建了这个项目,并为新的 MVC Core 2.0 应用程序(安装了 SDK)选择了默认值。
我已按照此处的步骤启用 program.cs 和 startup.cs 文件中的静态文件。 这些实现“app.UseStaticFiles();” 和“.UseContentRoot(Directory.GetCurrentDirectory())”。 通过谷歌找到的文章似乎都没有帮助。 我已验证 dotnet 已将静态内容复制到目标目录。
我错过了什么? 谢谢
// Program.cs
public static IWebHost BuildWebHost(string[] args) => WebHost
.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
// Startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseExceptionHandler("/Error/HandleError");
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute( name: "default", template: "{controller=User}/{action=Index}/{id?}");
});
}
我尝试了很多无用的东西,这对我来说是解决办法:
WebHost.CreateDefaultBuilder(args)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.UseWebRoot("E:\\xyz\\wwwroot")
.UseUrls("http://localhost:5050")
.Build();
我添加后立即开始提供静态文件:
.UseWebRoot("E:\\xyz\\wwwroot")
我的其中一台服务器在端口 5000 上运行时发生冲突,因此我指定在端口 5050 上启动。
.Net Core 2.2 更新
对于 .NET Core 2.2,以下工作: .UseWebRoot("wwwroot")
但是,获取路径的更易读和更明确的方法:
static string webRoot = Path.Combine(AppContext.BaseDirectory, "wwwroot");
然后UseWebRoot(webRoot);
我无法按照以下步骤使用新的 ASP.NET Core 2.0 项目重现您的错误;
css
。wwwroot/css
添加文件site.css
。app.UseStaticFiles();
在Startup.Configure()
方法的开头。 dotnet.exe
在我的终端中呈现以下输出:
Hosting environment: Production
Content root path: C:\src\static-test\pubweb
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/1.1 GET http://localhost:5000/css/site.css
info: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[2]
Sending file. Request path: '/css/site.css'. Physical path: 'C:\src\static-test\pubweb\wwwroot\css\site.css'
如您所见,它将成功正确地为子文件夹中的 css 文件提供服务。 请尝试上述步骤并将代码和输出与您失败的项目进行比较。 如果仍然失败,请在上面的Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware
附加有关Request
与Physical
路径的调试信息。
对我来说,问题是工作目录。 在尝试使用dotnet /var/www/project/project.dll
启动应用程序时,我没有注意我所在的目录。 当您以这种方式启动应用程序时,它会自动使用您的当前目录作为工作目录。
当我查看另一个项目的.service
文件时,我意识到了这一点,该文件指定了 WorkingDirectory:
...
WorkingDirectory=/var/www/project/
ExecStart=/usr/bin/dotnet /var/www/project/project.dll
...
因此,请确保在运行项目时位于正确的目录中,或者确保在.service
文件中正确设置了 WorkingDirectory。
我刚刚遇到了一个非常相似的问题。 我无法让 Kestrel 提供任何静态内容; 我有一个在 .net core 1.1 中运行良好的配置,但它在 .net core 2.0 中不起作用。
我调试通过它,静态文件中间件使用的 IFileProvider 实例是 NullFileProvider。 我必须在 Startup.cs 中执行此操作才能提供静态内容:
app.UseFileServer(
new FileServerOptions() {
FileProvider = new PhysicalFileProvider("some_path")
});
经过反复试验,我意识到一旦我开始使用 Kestrel,静态文件 web 根目录突然映射到 bin 文件夹而不是 development 文件夹。 要解决此问题,您可以执行以下两项操作之一。
您可以将根目录重新映射到某个路径:
.UseKestrel(...) .UseWebRoot(@"C:\\MyProject\\wwwroot\\");
我使用我开发的 wwwroot 文件夹,因此我不必确保所有新项目都添加到“复制到输出目录”中。
我使用 MS 模板创建了一个带有 asp.net core 2.1 (MVC) 的新项目,然后包含了一个带有一些动画的 css 文件animate.css 。
为了能够使用它,必须在_Layout.cshtml中添加一个href
因此,我注意到,MS“忘记”添加环境“Staging”和“Production”所以..如果在“Development”环境中添加href,则在调试(IIS Express)时一切正常,但它不适用于自主机(我假设也不在“真正的”IIS 上),因为这不是开发环境,并且未在运行时设置 href。
因此,我还为“暂存”和“生产”复制了“开发”环境(见下面的截图)。
<environment include="Development">
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/css/site.css" />
<link rel="stylesheet" href="~/css/animate.css">
</environment>
<environment exclude="Development">
<link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css"
asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
</environment>
@*<environment include="Staging,Production"> -> was missing completely!copy pasted from Development*@
<environment include="Staging,Production">
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/css/site.css" />
<link rel="stylesheet" href="~/css/animate.css">
</environment>
<environment exclude="Staging,Production">
<link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css"
asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
</environment>
@*End manually inserted*@
如果您在 Docker 中遇到此问题,您需要知道“root”基于您执行dotnet
命令的位置。 我不确定这是否最有意义,但事实就是如此。 很容易被绊倒的地方是,在执行命令之前,您需要确保 Docker 容器位于正确的目录中。
WORKDIR /app
# Example publish/build command:
RUN dotnet publish -o out
# Your publish folder is /app/out so...
# ENTRYPOINT ["dotnet", "/app/out/myapp.dll"]
# will run but you'll get 404s on all your static content.
# Instead use:
WORKDIR /app/out
ENTRYPOINT ["dotnet", "myapp.dll"]
不要使用我的脚本作为正确 Docker 发布脚本的示例。 这只是一个例子。
我有一个类似的问题。 (我在 Win 中开发并在 Linux 上托管,以防万一)。 只有几个文件有效(主要是默认文件),但我自己的内容导致了 404。
罪魁祸首是:文件和文件夹名称中的大写字母对我不起作用。 将所有内容都转换为小写,效果很好。
在 .NET Core 2.2 MVC 中遇到了同样的问题,将它作为带有“本地系统”用户的独立 Windows 服务运行。
问题是windows服务使用默认目录“C:\\Windows\\System32”,所以需要定义新路径:
.UseWebRoot(@"C:\MyProject\wwwroot\");
这是我用于在运行时检测路径的代码:
// Find app directory.
var isService = !(Debugger.IsAttached || args.Contains("--console"));
var currentDir = Directory.GetCurrentDirectory();
if (isService)
{
var pathToExe = Process.GetCurrentProcess().MainModule.FileName;
currentDir = Path.GetDirectoryName(pathToExe);
}
// Configure web host
var host = WebHost.CreateDefaultBuilder(args)
.UseKestrel()
.UseContentRoot(currentDir)
.UseWebRoot(Path.Combine(currentDir, "wwwroot"));
.UseStartup<Startup>()
.Build();
// Run.
if (isService)
{
host.RunAsService();
}
else
{
host.Run();
}
请检查以下标签中是否存在这些静态文件。
<environment include="Development">
</environment>
由于您已发布,如果静态文件存在于include Development
,则它们将不存在于Published文件夹中。 此外,检查View Source
并查看这些链接是否存在。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.