单文件 ASP.NET Core 5 Web 应用程序不加载静态资源

Mik*_*ike 9 c# asp.net-core .net-5

我正在尝试创建一个文件 asp.net core 5 Web 应用程序。目标是拥有一个 .exe 文件,通过执行此 exe 文件来运行 Kestrel 服务器并在浏览器中加载页面。

我在 VS 2019 中创建了一个 ASP.NET Core 5 模板应用程序。然后使用 cli 运行以下命令:

dotnet publish -c Release -r win-x64 /p:PublishSingleFile=true \n 
/p:IncludeNativeLibrariesForSelfExtract=true --self-contained true
Run Code Online (Sandbox Code Playgroud)

这会生成一个 exe 文件,当我将其复制到其他地方时,运行不会出现问题。但是当我浏览页面时,没有加载任何静态文件:

在此输入图像描述

生成单个文件 asp.net core 应用程序以便加载静态内容的正确方法是什么?

编辑

根据要求,将发布后输出的屏幕截图放在这里

在此输入图像描述

编辑2

要获得可重现的项目:

Visual Studio 2019 -> 新解决方案 -> ASP.NET Core Web App,配置如下

在此输入图像描述

编辑3

感谢@JHBonarius 的回答,我更改了 Program.cs 以设置为提取内容的ContentRoot临时文件夹。wwwroot

public class Program
    {
        public static void Main(string[] args)
        {
            var path = Path.Combine(Path.GetTempPath(), ".net", typeof(Program).Assembly.GetName().Name);

            var directory = 
                Directory
                    .GetDirectories(path)
                    .Select(path => new DirectoryInfo(path))
                    .OrderByDescending(di => di.LastWriteTime)
                    .First();

            CreateHostBuilder(args)
                .UseContentRoot(directory.FullName)
                .Build()
                .Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)            
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }
Run Code Online (Sandbox Code Playgroud)

虽然我意识到这看起来像是一个黑客(我找不到这条路径的任何官方文档),但我想要一些工作代码。

通过这些更改,页面现在加载静态资源,但不是全部。

wwwroot这是解决方案资源管理器中文件夹的内容

在此输入图像描述

wwwroot这是临时路径上提取的文件夹的内容

在此输入图像描述 在此输入图像描述

可以看出,js/css文件夹以及jquery-validation&jquery-validation-unobtrusive文件夹都丢失了。

知道发生了什么事吗?

我创建了一个包含最新更改的github 存储库。

Józ*_*cki 7

我尝试在新的 asp net core 空项目上重现您的问题,并且工作正常。

也许启动缺少一些配置。

这就是我所做的。

工程项目

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>
</Project>
Run Code Online (Sandbox Code Playgroud)

启动.cs

public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseDefaultFiles();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseEndpoints(endpoints => {});
        }
    }
Run Code Online (Sandbox Code Playgroud)

wwwroot

与您的情况类似,还有引导程序。

wwwroot 内容

索引.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>TEST</title>
    <link href="css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <script src="js/bootstrap.min.js"></script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

-- 2021 年 11 月 29 日更新

我的期望是 .exe 将是一个独立的捆绑包,并且在执行时它将提取静态文件并能够解析对其的引用。事实似乎并非如此。

好吧,那么你必须将 wwwroot 中的所有内容标记为嵌入式资源

<PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
   <GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>
</PropertyGroup>

<ItemGroup>
    <Compile Remove="wwwroot\**" />
    <Content Remove="wwwroot\**" />
     <EmbeddedResource Include="wwwroot\**\*">
      <Link>wwwroot\%(RecursiveDir)%(Filename)%(Extension)</Link>
      <LogicalName>wwwroot\%(RecursiveDir)%(Filename)%(Extension) 
      </LogicalName>
    </EmbeddedResource>
    <None Remove="wwwroot\**" />
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)

Configure(IApplicationBuilder, IWebHostEnvironment)并在方法中执行文件提取

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>
</Project>
Run Code Online (Sandbox Code Playgroud)

如果您不喜欢这种方法,您可以考虑EmbeddedFileProvider

Startup.cs:配置

public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseDefaultFiles();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseEndpoints(endpoints => {});
        }
    }
Run Code Online (Sandbox Code Playgroud)

工程项目

<EmbeddedResource Include="wwwroot\**\*" />
Run Code Online (Sandbox Code Playgroud)