[英]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.