如何打造单文件前后端集成 ASP.NET Core 应用

问题

今天在 github 上看到有人用中文提问,老外需要使用谷歌翻译来了解这个问题在说啥,真有我们看不懂英文文档时的既视感(笑).

如何打造单文件前后端集成 ASP.NET Core 应用

问题希望提供一个选项,可以将“wwwroot”打包到“SingleFileDemo.ext”中,实现真正的“生成单个文件”。

在前面的文章中,我们介绍过《如何生成前后端集成项目》。

它的实现原理是发布 Web API 时自动编译前端项目,并将前端文件复制到 Web API 的 wwwroot 目录下。

但是,这样生成的部署包包含了很多文件。

虽然,ASP.NET Core 支持发布成单个文件的:

如何打造单文件前后端集成 ASP.NET Core 应用

但是这种方式,不能将前端发布文件包含进去。

如何打造单文件前后端集成 ASP.NET Core 应用

我们想达到的目的,是前后端都在同一个 EXE 文件里

思路

在《怎么实现动态设置静态文件存储目录?》文章中,我们了解到,静态文件中间件可以配置读取位置。

默认情况下,FileProvider 是读取本地物理文件。

如果改成从 EXE 文件中读取静态文件的 FileProvider,不就实现了我们的目的了吗?!

而实际上,.NET 已经提供了这样一个 FileProvider:ManifestEmbeddedFileProvider[1],用于访问嵌入在程序集中的文件。

实现

  1. 将 Microsoft.Extensions.FileProviders.Embedded NuGet 包添加到 Web API 项目。

  2. 修改项目文件,将 GenerateEmbeddedFilesManifest 属性设置为 true,并指定嵌入的文件来源:

<PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
     <GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>
</PropertyGroup>

<ItemGroup>
    <EmbeddedResource Include="wwwroot\**" />
</ItemGroup>
  1. 修改 Program.cs,设置静态文件中间件:
app.UseFileServer(new FileServerOptions
{
    FileProvider = new ManifestEmbeddedFileProvider(
        typeof(Program).Assembly, "wwwroot"
    )
});
  1. 发布 Web API,将生成的独立 EXE 文件进行部署。可以看到,不依赖任何其他文件,前后端功能使用正常:

如何打造单文件前后端集成 ASP.NET Core 应用

结论

今天,我们通过使用ManifestEmbeddedFileProvider,打造出了单文件前后端集成应用。