如何将 SPA 嵌入 ASP.NET Core 库并从路径提供服务

IT技术 angular reactjs asp.net-core asp.net-core-middleware asp-net-core-spa-services
2021-05-14 05:07:52

塞纳里奥

我想构建一个包含小型SPA前端的 aspnetcore 库/module即 html/js/css 文件应该与 dll 一起出现。该SPA应该从一个特定的路径送达,即/some-module(并没有需要进行配置)。SPA 由几个 html/js/css 文件组成,让我们假设以下文件:

/my-module/index.html
/my-module/index.js
/my-module/index.css

这些 url 应该只是服务器文件。所有其他路径,例如

/my-module/
/my-module/page-1
/my-module/page-2

应该为 index.html 提供服务,以便客户端路由可以处理请求。

我有一个部分解决方案,其中提供 SPA 文件。但是我不知道如何使所有其他子路径即/my-module/*(不包括文件)返回index.html.

使用嵌入文件和 UseFileServer 的部分解决方案:

假设 SPA 构建文件位于/my-library/web/build/. 以下 csproj 使用GenerateEmbeddedFilesManifest将这些文件嵌入到 dll 中EmbeddedResource

my-module.csproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>
    <SpaRoot>web\</SpaRoot>
    <DefaultItemExcludes>$(DefaultItemExcludes);$(SpaRoot)node_modules\**</DefaultItemExcludes>
  </PropertyGroup>

  <ItemGroup>
    <Folder Include="web\" />
  </ItemGroup>

  <ItemGroup>
    <EmbeddedResource Include="web\build\**" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="2.2.0" />
    <PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="2.2.0" />
    <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" />
  </ItemGroup>

</Project>

以下中间件配置使用以下内容提供这些嵌入文件ManifestEmbeddedFileProvider

        public static void UseMyModuleUi(this IApplicationBuilder app)
        {
            app.UseFileServer(new FileServerOptions
            {
                RequestPath = "/my-module",
                FileProvider = new ManifestEmbeddedFileProvider(
                    assembly: Assembly.GetAssembly(typeof(ServiceExtensions)), "web/build")
            });
        }

UseMyModuleUi在引用我的module的某些 aspnetcore 应用程序中调用扩展方法,这确实为下面的文件提供服务 /my-module/index.html /my-module/index.js /my-module/index.css

甚至/my-module/服务my-module/index.html

但是,/my-module/例如下的所有其他路径my-module/page-1不提供服务index.html。#

我试过的替代方案

我尝试使用UseSpaStaticFilesorUseStaticFiles和 的一些组合Map,但是没有很好的结果。

我正在构建的项目可在此处获得:https : //github.com/jannikbuschke/ef-configuration-providerui项目是嵌入 SPA 的库。sample项目是宿主应用程序。

1个回答

以下应该对你有用:

    public static void UseMyModuleUi(this IApplicationBuilder app)
    {
        app.Map("/my-module", builder => 
        {
            var provider = new ManifestEmbeddedFileProvider(
                assembly: Assembly.GetAssembly(typeof(ServiceExtensions)), "web/build"); 
            builder.UseStaticFiles(new StaticFileOptions 
            {
                FileProvider = provider
            });
            builder.Run(async context =>
            {
                await context.Response.SendFileAsync(provider.GetFileInfo("index.html"));
            });
        });
    }
  1. Map 定义一个新分支,当请求以给定路径开始时执行,并从该分支中​​删除该路径段。
  2. 静态文件提供程序将匹配存在于 ManifestEmbeddedFileProvider
  3. 为了index.html为每个不匹配的请求提供服务,Run定义一个始终返回给定文件的委托。这就是你所谓的这个分支的全能