繁体   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