How to host an Angular app inside .NET Core 3.1 WebAPI?
Asked Answered
S

2

10

I want to provide my Angular app through the root route / and the REST API through /api/*. For the Angular routing I have to redirect all requests to /index.html except the requests for existing files (e.g. media files) and my API controller routes.

With the Startup.cs below it's close to be working:

The following is not working: Refreshing or opening directly http://localhost:5000/home will end up in a 404. I guess /home is not redirected to the index.html. What I'm missing here?

public class Startup
{
    private readonly IWebHostEnvironment _webHostEnvironment;

    public Startup(IWebHostEnvironment webHostEnvironment)
    {
      _webHostEnvironment = webHostEnvironment;
    }
    public void ConfigureServices(IServiceCollection services)
    {        
      services.AddSpaStaticFiles(options =>
      {
        options.RootPath = "wwwroot";
      });

      services.AddControllers();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
      app.UseDefaultFiles();
      app.UseSpaStaticFiles();
      app.UseCors();
      app.UseSwagger();
      app.UseSwaggerUI(c => { /*...*/ });
      app.UseRouting();
      app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
    }
}
Soulful answered 27/5, 2020 at 22:7 Comment(0)
F
10

Your are missing one important thing for SPA hosting:

app.UseSpa(spa =>
{
    // To learn more about options for serving an Angular SPA from ASP.NET Core,
    // see https://go.microsoft.com/fwlink/?linkid=864501
});

Handles all requests from this point in the middleware chain by returning the default page for the Single Page Application (SPA).

This middleware should be placed late in the chain, so that other middleware for serving static files, MVC actions, etc., takes precedence.

- https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.builder.spaapplicationbuilderextensions.usespa


Update: If you only want to map a specific route to the index.html i.e. everything starting with http://localhost/ui/ you can combine it with app.MapWhen

app.MapWhen(
    context => context.Request.Path.StartsWithSegments("/ui/", StringComparison.OrdinalIgnoreCase), 
    cfg => 
    {
        cfg.UseSpa(spa =>
        {
            // To learn more about options for serving an Angular SPA from ASP.NET Core,
            // see https://go.microsoft.com/fwlink/?linkid=864501
        });
    }
);
Fortner answered 28/5, 2020 at 7:44 Comment(3)
Just wandering, is it possible to directly using CND url to host SPA in AspNetCore?Submultiple
app.UseSpa is no longer supported in .NET 6Disarrange
@GerardoBuenrostroGonzález well the extension method for that still exists for net6: learn.microsoft.com/en-us/dotnet/api/… do you have the nuget package Microsoft.AspNetCore.SpaServices.Extensions version 6.0.0 installed?Fortner
M
5

I had the same problem but app.UseSpa(...) did not work as I guess I was missing some dependecies.

Alternativele you could add endpoints.MapFallbackToFile("/index.html"); in app.UseEndpoints(..), which is part of the Microsoft.AspNetCore.StaticFiles assembly.

So it would look like this:

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
    endpoints.MapFallbackToFile("/index.html");
});

Source: https://weblog.west-wind.com/posts/2020/Jul/12/Handling-SPA-Fallback-Paths-in-a-Generic-ASPNET-Core-Server#server-side-navigation-of-client-side-routes

Munda answered 24/11, 2020 at 15:48 Comment(1)
.net 6 does not support app.UseSpa but your answer worked.Protoplast

© 2022 - 2024 — McMap. All rights reserved.