Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle multiple SPA application in ASP.NET Core

I have an ASP.NET Core Web API application, I want to serve two Angular apps, one for admin and one for users.

In production, I don't use angular CLI tools so there is only some static files of two angular web applications.

Admin files are in /angular/admin and user files are in /angular/user. So, how can I serve them?

I tried multiple calls to IServiceCollection.AddSpaStaticFiles but they override each other. [From source repository I found this is Singleton services]

like image 400
oMid dehghani Avatar asked Jun 06 '19 17:06

oMid dehghani


People also ask

Can ASP.NET Core handle many requests?

ASP.NET Core apps should be designed to process many requests simultaneously. Asynchronous APIs allow a small pool of threads to handle thousands of concurrent requests by not waiting on blocking calls. Rather than waiting on a long-running synchronous task to complete, the thread can work on another request.

Can we have multiple middleware in .NET Core?

Typically, there will be multiple middleware in ASP.NET Core web application. It can be either framework provided middleware, added via NuGet or your own custom middleware. We can set the order of middleware execution in the request pipeline.

What is SpaServices?

SpaServices was created to position ASP.NET Core as developers' preferred server-side platform for building SPAs. SpaServices isn't required to develop SPAs with ASP.NET Core, and it doesn't lock developers into a particular client framework. SpaServices provides useful infrastructure such as: Server-side prerendering.

What is UseProxyToSpaDevelopmentServer?

UseProxyToSpaDevelopmentServer(ISpaBuilder, Uri) Configures the application to forward incoming requests to a local Single Page Application (SPA) development server. This is only intended to be used during development. Do not enable this middleware in production applications.


2 Answers

You have to branch the application middleware pipeline into two and register the SPAs after setting up MVC

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

                ```
like image 125
Avin Kavish Avatar answered Nov 14 '22 21:11

Avin Kavish


another tip: I'm using react and the react-router cannot handle path in URL correctly. So I use a different port for different spa. Use "app.MapWhen(o => o.Request.Host == 6000, ...)" to handle this case.

In production, should be something like : MapWhen(o => o.Request.Host.Host == "a.com"...

like image 25
Mason Zhang Avatar answered Nov 14 '22 22:11

Mason Zhang