简体   繁体   English

Asp.Net Core 2.0-2.2 Kestrel 不提供静态内容

[英]Asp.Net Core 2.0-2.2 Kestrel not serving static content

When running a Asp.Net Core 2.0 (or 2.2) app using IIS express, static files (css, js) are served as expected.使用 IIS express 运行 Asp.Net Core 2.0(或 2.2)应用程序时,静态文件(css、js)按预期提供。 However when using command line/Kestrel via "dotnet publish -o [targetDirectory]" and dotnet [website.dll], Kestrel does not serve up any static content.但是,当通过“dotnet publish -o [targetDirectory]”和 dotnet [website.dll] 使用命令行/Kestrel 时,Kestrel 不提供任何静态内容。 Utilizing browser F12, I see Kestrel returns a 404 error.使用浏览器 F12,我看到 Kestrel 返回 404 错误。 Looking closer, when entering the file path directly in the browser (localhost:5000/ css /cssfile.css) the file is not displayed but the browser appears to redirect to "localhost:5000/cssfile.css" but still returns a 404 error (note the missing /css/ directory).仔细一看,在浏览器中直接输入文件路径(localhost:5000/ css /cssfile.css)时,文件没有显示,但浏览器似乎重定向到“localhost:5000/cssfile.css”,但仍然返回404错误(注意缺少的 /css/ 目录)。

I created this project via Visual Studio 2017, and chose the defaults for a new MVC Core 2.0 application (SDK was installed).我通过 Visual Studio 2017 创建了这个项目,并为新的 MVC Core 2.0 应用程序(安装了 SDK)选择了默认值。

I have followed the steps here to enable static files in the program.cs and startup.cs files.我已按照此处的步骤启用 program.cs 和 startup.cs 文件中的静态文件。 These implement "app.UseStaticFiles();"这些实现“app.UseStaticFiles();” and ".UseContentRoot(Directory.GetCurrentDirectory())".和“.UseContentRoot(Directory.GetCurrentDirectory())”。 None of the articles found via google seem to help.通过谷歌找到的文章似乎都没有帮助。 I have verified dotnet copied the static content to the target directory.我已验证 dotnet 已将静态内容复制到目标目录。

What am I missing?我错过了什么? Thanks谢谢

// 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?}");
    });
}

I tried so many useless things, this was the fix for me:我尝试了很多无用的东西,这对我来说是解决办法:

WebHost.CreateDefaultBuilder(args)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.UseWebRoot("E:\\xyz\\wwwroot")
.UseUrls("http://localhost:5050")
    .Build();

Serving static files started working as soon as I added:我添加后立即开始提供静态文件:

.UseWebRoot("E:\\xyz\\wwwroot")

I got a conflict on one of my servers running on port 5000, so I specified to start on port 5050.我的其中一台服务器在端口 5000 上运行时发生冲突,因此我指定在端口 5050 上启动。


Update for .Net Core 2.2 .Net Core 2.2 更新

For .NET Core 2.2, the following works: .UseWebRoot("wwwroot")对于 .NET Core 2.2,以下工作: .UseWebRoot("wwwroot")

However, a more readable and explicit approach to get the path:但是,获取路径的更易读和更明确的方法:

static string webRoot = Path.Combine(AppContext.BaseDirectory, "wwwroot");

and then UseWebRoot(webRoot);然后UseWebRoot(webRoot);

I am unable to reproduce your error using a fresh ASP.NET Core 2.0 project following these steps;我无法按照以下步骤使用新的 ASP.NET Core 2.0 项目重现您的错误;

  1. md static-test md 静态测试
  2. cd static-test cd 静态测试
  3. dotnet new web dotnet 新网站
  4. Add folder css in wwwroot.在 wwwroot 中添加文件夹css
  5. Add file site.css in wwwroot/css .wwwroot/css添加文件site.css
  6. Insert app.UseStaticFiles();插入app.UseStaticFiles(); at the start of Startup.Configure() method.Startup.Configure()方法的开头。
  7. dotnet publish -o pubweb dotnet 发布 -o pubweb
  8. cd pubweb cd pubweb
  9. dotnet .\\static-test.dll dotnet .\\static-test.dll
  10. Access http://localhost:5000/css/site.css using browser.使用浏览器访问http://localhost:5000/css/site.css

dotnet.exe renders the following output in my terminal: 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'

As you can see it will successfully serve the css file within a subfolder correctly.如您所见,它将成功正确地为子文件夹中的 css 文件提供服务。 Please try the above steps and compare the code and output with your failing project.请尝试上述步骤并将代码和输出与您失败的项目进行比较。 If it is still failing, please attach the debug info on Request vs. Physical path from Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware above.如果仍然失败,请在上面的Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware附加有关RequestPhysical路径的调试信息。

For me, the problem was the working directory.对我来说,问题是工作目录。 I wasn't paying attention to the directory I was in when trying to launch the app with dotnet /var/www/project/project.dll .在尝试使用dotnet /var/www/project/project.dll启动应用程序时,我没有注意我所在的目录。 It automatically uses your current directory as the working directory when you launch the app this way.当您以这种方式启动应用程序时,它会自动使用您的当前目录作为工作目录。

I realized this when I looked at a .service file for another project, which has the WorkingDirectory specified:当我查看另一个项目的.service文件时,我意识到了这一点,该文件指定了 WorkingDirectory:

...
WorkingDirectory=/var/www/project/
ExecStart=/usr/bin/dotnet /var/www/project/project.dll
...

So, either make sure you are in the correct directory when you run your project, or ensure that the WorkingDirectory is properly set in your .service file.因此,请确保在运行项目时位于正确的目录中,或者确保在.service文件中正确设置了 WorkingDirectory。

I just ran into a very similar issue.我刚刚遇到了一个非常相似的问题。 I couldn't get Kestrel to serve up any static content;我无法让 Kestrel 提供任何静态内容; I had a config that worked fine in .net core 1.1, but it wouldn't work in .net core 2.0.我有一个在 .net core 1.1 中运行良好的配置,但它在 .net core 2.0 中不起作用。

I debugged through it and the IFileProvider instance used by the static file middleware was NullFileProvider.我调试通过它,静态文件中间件使用的 IFileProvider 实例是 NullFileProvider。 I had to do this in Startup.cs to get static content served:我必须在 Startup.cs 中执行此操作才能提供静态内容:

app.UseFileServer(
    new FileServerOptions() {
        FileProvider = new PhysicalFileProvider("some_path")
    });

After trial and error I realized that once I begin using Kestrel, the static files web root is suddenly mapped to the bin folder instead of the development folder.经过反复试验,我意识到一旦我开始使用 Kestrel,静态文件 web 根目录突然映射到 bin 文件夹而不是 development 文件夹。 To fix this you can do one of two things.要解决此问题,您可以执行以下两项操作之一。

  1. You can set all of the static files you want to include to Copy to Output Directory您可以将要包含的所有静态文件设置为复制到输出目录
  2. You can remap the root directory to a certain path:您可以将根目录重新映射到某个路径:

     .UseKestrel(...) .UseWebRoot(@"C:\\MyProject\\wwwroot\\");

I use the wwwroot folder that I develop in so I don't have to ensure all new items get added to Copy to Output Directory.我使用我开发的 wwwroot 文件夹,因此我不必确保所有新项目都添加到“复制到输出目录”中。

I have create an new project with asp.net core 2.1 (MVC) with the MS template and then have included a css file animate.css with some animations.我使用 MS 模板创建了一个带有 asp.net core 2.1 (MVC) 的新项目,然后包含了一个带有一些动画的 css 文件animate.css

To be able to use it, a href has to be added in _Layout.cshtml为了能够使用它,必须在_Layout.cshtml中添加一个href
Thereby, I have noted, that MS has "forgotten" to add the environments "Staging" and "Production" So.. if the href is added in the "Development" environment, everything works fine in debugging (IIS Express), but it don't works with a selfhost (and I assume also not on "the real" IIS), as this is not the Development environment and the hrefs's are not set at runtime.因此,我注意到,MS“忘记”添加环境“Staging”和“Production”所以..如果在“Development”环境中添加href,则在调试(IIS Express)时一切正常,但它不适用于自主机(我假设也不在“真正的”IIS 上),因为这不是开发环境,并且在运行时设置 href。
Therefore I have copy -pasted the "Development" environment also for "Staging" and "Production" (see snipped below).因此,我还为“暂存”和“生产”复制了“开发”环境(见下面的截图)。

  <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*@

If you're running into this in Docker you need to know that the "root" is based on where you're executing the dotnet command.如果您在 Docker 中遇到此问题,您需要知道“root”基于您执行dotnet命令的位置。 I'm not sure this makes the most sense, but it is what it is.我不确定这是否最有意义,但事实就是如此。 Where it's easy to get tripped up is you need to make sure your Docker container is in the correct directory before executing the command.很容易被绊倒的地方是,在执行命令之前,您需要确保 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"]

Don't use my script as an example of a proper Docker publish script.不要使用我的脚本作为正确 Docker 发布脚本的示例。 It's just an example.这只是一个例子。

I had a similar issue.我有一个类似的问题。 (I developed in Win and hosted on Linux, in case it makes a difference). (我在 Win 中开发并在 Linux 上托管,以防万一)。 Just a few files worked (mostly default ones), but my own content caused 404.只有几个文件有效(主要是默认文件),但我自己的内容导致了 404。

The culprit was: capitals in file and folder names didn't work for me .罪魁祸首是:文件和文件夹名称中的大写字母对我不起作用 Converted everything to lower case and it works fine.将所有内容都转换为小写,效果很好。

Had the same problem in .NET Core 2.2 MVC, running it as self-contained windows service with "Local system" user.在 .NET Core 2.2 MVC 中遇到了同样的问题,将它作为带有“本地系统”用户的独立 Windows 服务运行。

The problem is that windows services use default directory in "C:\\Windows\\System32", so you need to define new path:问题是windows服务使用默认目录“C:\\Windows\\System32”,所以需要定义新路径:

.UseWebRoot(@"C:\MyProject\wwwroot\");

Here is code I use for detecting path in runtime:这是我用于在运行时检测路径的代码:

// 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();
}

Please check whether those static files are present within the below tags.请检查以下标签中是否存在这些静态文件。

<environment include="Development">
</environment>

As you have Published, if the static files are present inside the include Development , then they will not be present in the Published folder.由于您已发布,如果静态文件存在于include Development ,则它们将不存在于Published文件夹中。 Also, Check View Source and see whether those links are present or not.此外,检查View Source并查看这些链接是否存在。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM