【问题标题】:How to handle multiple SPA application in ASP.NET Core如何在 ASP.NET Core 中处理多个 SPA 应用程序
【发布时间】:2022-05-19 23:13:12
【问题描述】:

我有一个 ASP.NET Core Web API 应用程序,我想为两个 Angular 应用程序提供服务,一个用于管理员,一个用于用户。

在生产中,我不使用 Angular CLI 工具,因此只有两个 Angular Web 应用程序的一些静态文件。

管理文件位于/angular/admin,用户文件位于/angular/user。 那么,我该如何为他们服务呢?

我尝试多次调用IServiceCollection.AddSpaStaticFiles,但它们相互覆盖。 [从源代码库我发现这是单例服务]

【问题讨论】:

    标签: c# asp.net-core


    【解决方案1】:

    您必须将应用程序中间件管道一分为二,并在设置 MVC 后注册 SPA

     ...
     app.UseMvc(...)
    
     app.Map("/admin",
       adminApp =>
       {
         adminApp.UseSpa(spa =>
         {
           spa.Options.SourcePath = "angular/admin";
           spa.Options.DefaultPageStaticFileOptions = new StaticFileOptions
           {
               FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "angular", "admin"))
           };
    
           if (env.IsDevelopment())
             spa.UseProxyToSpaDevelopmentServer("http://localhost:4200");
          });
        });
    
      app.Map("/user",
        userApp =>
        {
          userApp.UseSpa(spa =>
          {
            spa.Options.SourcePath = "angular/user";
            spa.Options.DefaultPageStaticFileOptions = new StaticFileOptions
            {
                FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "angular", "user"))
            };
    
            if (env.IsDevelopment())
              spa.UseProxyToSpaDevelopmentServer("http://localhost:4201");
          });
      });  
    
                    ```
    

    【讨论】:

    • 我写了你说的但仍然得到 SPA 默认页面中间件无法返回默认页面'/index.html' ...错误,直到我使用@987654323 @ 将IApplicationBuilder 分隔为两个appUserappAdmin,然后使用appUser.UseSpa(spa => spa.Options.DefaultPageStaticFileOptions = staticFileOptionsUser);appAdmin.UseSpa(spa => spa.Options.DefaultPageStaticFileOptions = staticFileOptionsAdmin);。感谢您的回复。
    • 是的,这就是我通常所做的,但我想给你这个解决方案,看看它是否有效。 xD您无论如何都必须拆分管道吗?或者你在开发过程中是否在 asp net core 之外使用了 angular cli?
    • 那么没有UseSpa 就不行了:)。是的,我应该分开。
    • 还有一个快速提示,我使用UseProxyToSpaDevelopmentServer 而不是UseAngularCliServer 并手动启动 angular cli,否则每次更改 c# 代码时 angular cli 都会重新启动。 docs.microsoft.com/en-us/dotnet/api/…
    • 是的,这正是我在开发环境中所做的
    【解决方案2】:

    另一个提示:我正在使用 react,react-router 无法正确处理 URL 中的路径。所以我为不同的水疗中心使用不同的端口。使用“app.MapWhen(o => o.Request.Host == 6000, ...)”来处理这种情况。

    在生产中,应该类似于: MapWhen(o => o.Request.Host.Host == "a.com"...

    【讨论】:

      【解决方案3】:

      我想从基于 dotnet React 的应用程序中提供 Outlook 插件。这就是我能够让它同时用于开发和生产的方法。

          public void ConfigureServices(IServiceCollection services)
          {
              ...
              services.AddSpaStaticFiles(configuration =>
              {
                  configuration.RootPath = "ClientApp/build";
              });
              ...
          }
          
      
          public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
          {
            ...          
      
            
              
              app.Map("/addin",
                 addin =>
                 {
                     var sfo = new StaticFileOptions()
                     {
                         OnPrepareResponse = ctx =>
                         {
                             var resp = ctx.Context.Response;
                             resp.Headers[HeaderNames.CacheControl] = "no-cache, no-store, must-revalidate";
                             resp.Headers[HeaderNames.Expires] = "0";
                             resp.Headers[HeaderNames.Pragma] = "no-cache";
                         }
                     };
                     if (!env.IsDevelopment())
                     {
                         var dir = Path.Combine(Directory.GetCurrentDirectory(), "OutlookAddinApp/dist");
                         sfo.FileProvider = new PhysicalFileProvider(dir);
                     }
                     addin.UseSpaStaticFiles(sfo);
                     addin.UseSpa(spa =>
                     {
                         spa.Options.SourcePath = "OutlookAddinApp";
                         spa.Options.DefaultPage = "/taskpane.html";
                         spa.Options.DefaultPageStaticFileOptions = sfo;
      
                         if (env.IsDevelopment())
                         {
                             spa.Options.StartupTimeout = TimeSpan.FromMinutes(2);
                             spa.UseProxyToSpaDevelopmentServer("https://localhost:3000");
                         }
                     });
                 })
                 .Map("",
                  root =>
                  {
                      var sfo = new StaticFileOptions()
                      {
                          OnPrepareResponse = ctx =>
                          {
                              var resp = ctx.Context.Response;
                              resp.Headers[HeaderNames.CacheControl] = "no-cache, no-store, must-revalidate";
                              resp.Headers[HeaderNames.Expires] = "0";
                              resp.Headers[HeaderNames.Pragma] = "no-cache";
                          }
                      };
                      if (!env.IsDevelopment())
                      {
                          var dir = Path.Combine(Directory.GetCurrentDirectory(), "ClientApp/build");
                          sfo.FileProvider = new PhysicalFileProvider(dir);
                      }
                      root.UseSpaStaticFiles(sfo);
                      root.UseSpa(spa =>
                      {
                          spa.Options.SourcePath = "ClientApp";
                          spa.Options.DefaultPageStaticFileOptions = sfo;
      
                          if (env.IsDevelopment())
                          {
                              spa.Options.StartupTimeout = TimeSpan.FromMinutes(2);
                              spa.UseReactDevelopmentServer(npmScript: "start");
                          }
                      });
                  });
        }
      

      【讨论】:

        猜你喜欢
        • 2020-10-24
        • 1970-01-01
        • 2019-04-28
        • 2020-07-07
        • 2018-10-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多