【问题标题】:How to embed a SPA into an ASP.NET Core library and serve it from a path如何将 SPA 嵌入 ASP.NET Core 库并从路径提供服务
【发布时间】:2020-05-14 21:03:27
【问题描述】:

情景

我想构建一个 包含 小型 SPA 前端的 aspnetcore 库/模块。 IE。 html/js/css 文件应该与 dll 一起提供。 SPA 应从特定路径提供服务,即/some-modulenot 是否需要可配置)。 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 使用 GenerateEmbeddedFilesManifestEmbeddedResource 将这些文件嵌入到 dll 中:

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

在一些引用我的模块的 aspnetcore 应用程序中调用 UseMyModuleUi 扩展方法,这确实为下面的文件提供服务 /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.#

我尝试过的替代方案

我尝试使用UseSpaStaticFilesUseStaticFilesMap 的一些组合,但效果不佳。

我正在构建的项目在这里可用:https://github.com/jannikbuschke/ef-configuration-provider ui 项目是嵌入 SPA 的库。 sample 项目是宿主应用程序。

【问题讨论】:

  • 你最终能找到解决办法吗?
  • 不,我只找到了上面的部分解决方案,这对于我的用例来说不够灵活。因此,我不会转向前端具有专用 npm 包的方法,该包可以在应用程序中使用。从应用程序的角度来看,这种方法可以提供更大的灵活性,但要正确设置有点麻烦。

标签: angular reactjs asp.net-core asp.net-core-middleware asp-net-core-spa-services


【解决方案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.htmlRun 定义了一个始终返回给定文件的委托。这就是这个分支的所谓catch-all

【讨论】:

    猜你喜欢
    • 2020-12-12
    • 2019-11-21
    • 2017-06-08
    • 2018-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-15
    • 1970-01-01
    相关资源
    最近更新 更多