UseSpa() returns index.html from API instead of 404

Viewed 1922

By default .UseSpa() in startup.cs catches every request that arrives to its point of the pipeline, and tries to handle it as a request to the SPA main page

I want to keep 404 for for my API calls at route /api/* just in case when typo in api url is made it my logger would log 404 and and not like "Error Code: 200 Message: Http failure during parsing for https://localhost:5001/api/non-existing-api-should-give-404" (because it got index.html in response)

Already spend over day on this and I can't find solution :( UseSpa() seems to overwrite any not matched endpoint. Any ideas how to solve it?

Here is basic configure from Startup.cs, problem is in Production Environment.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseHttpsRedirection();
            if (!env.IsDevelopment())
            {
                app.UseSpaStaticFiles();
            }

            app.UseRouting();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });

            app.UseSpa(spa =>
            {
                if (env.IsDevelopment())
                {
                    spa.UseProxyToSpaDevelopmentServer("http://127.0.0.1:4200");
                }
            });
        }
1 Answers

The UseSpa middlware is a catch-all, and any request that gets to that point will always have the default SPA page returned. This means any request to a route that hasn't yet found a controller will always return the default SPA page, and not throw a 404.

What you will want to do it only call UseSpa() if the route is not prefixed with /api. Which essentially lets any requests that start with/api skip past that point.

Change:

app.UseSpa(spa =>
{
    //...
});

To:

app.MapWhen(x => !x.Request.Path.Value.StartsWith("/api"), builder =>
{
    builder.UseSpa(spa =>
    {
        //...
    });
});

This will let any request that starts with /api past that point, and if no other middleware or routes are matched, a 404 will be returned.

Related