Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return 404 on wrong API url? (ASP.NET Core + SPA)

I need to return 404 on wrong api call so I can create proper response to user on client side (Angular 5). Currently backend returns status code 200 and index.html, and that results in json parse error on frontend.

I created new web project with ASP.NET Core 2.1 and Angular template project. Here's the link to published version of that template. I didn't change template code at all, I just published that on azure as it is. (In dev mode I get 404 error as expected).

As mentioned here default behaviour should be 404.

Here is the Startup.cs, and here SampleDataController.cs.

I thought of using something like this in Startup.cs:

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller}/{action}/{id?}");
        });

        app.MapWhen(x => x.Request.Path.Value.Contains("/api"), builder =>
        {
            builder.UseMvc(routes =>
            {
                routes.MapSpaFallbackRoute(
                    name: "spa-fallback",
                    defaults: new { controller = "Home", action = "Error" });
            });
        });

And in HomeController.cs:

    public IActionResult Error()
    {
        return NotFound();
    }

But that seems wrong although it works.

like image 546
Martina Grgić Avatar asked Sep 16 '18 21:09

Martina Grgić


People also ask

How does Web API handle 404 error?

A simple solution is to check for the HTTP status code 404 in the response. If found, you can redirect the control to a page that exists. The following code snippet illustrates how you can write the necessary code in the Configure method of the Startup class to redirect to the home page if a 404 error has occurred.

How do I return a status code in Web API .NET core?

HTTP Status Code 201 is used to return Created status i.e., when request is completed and a resource is created. Such HTTP Response it is returned using Created function. Optionally, you can also return, the URL where the object is created and also an object along with the HTTP Response Created.


1 Answers

Note: Based on your links, I assume you are using the app.UseSpa() middleware.

The route middleware is executed in order, and if the request never finds a controller a 404 status is returned. 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.

Instead of:

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

Use:

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

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.

like image 147
Douglas Gaskell Avatar answered Sep 22 '22 10:09

Douglas Gaskell