簡體   English   中英

Asp.Net Core 2.0-2.2 Kestrel 不提供靜態內容

[英]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 項目重現您的錯誤;

  1. md 靜態測試
  2. cd 靜態測試
  3. dotnet 新網站
  4. 在 wwwroot 中添加文件夾css
  5. wwwroot/css添加文件site.css
  6. 插入app.UseStaticFiles(); Startup.Configure()方法的開頭。
  7. dotnet 發布 -o pubweb
  8. cd pubweb
  9. dotnet .\\static-test.dll
  10. 使用瀏覽器訪問http://localhost:5000/css/site.css

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附加有關RequestPhysical路徑的調試信息。

對我來說,問題是工作目錄。 在嘗試使用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 文件夾。 要解決此問題,您可以執行以下兩項操作之一。

  1. 您可以將要包含的所有靜態文件設置為復制到輸出目錄
  2. 您可以將根目錄重新映射到某個路徑:

     .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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM