如何在ASP.NET Core + SPA中对错误的API URL返回404?

14

我需要在错误的API调用时返回404状态码,这样我就可以在客户端(Angular 5)上创建适当的响应。目前后端返回状态码200和index.html,结果导致前端出现JSON解析错误。

我使用ASP.NET Core 2.1和Angular模板项目创建了一个新的Web项目。这里是该模板发布版本的链接。我没有改变模板代码,只是将其作为原样发布到Azure。(在开发模式下,我得到了预期的404错误)。

此处所述,默认行为应该是404。

这里Startup.cs文件,这里SampleDataController.cs文件。

我考虑在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" });
            });
        });

然后在HomeController.cs中:

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

但那似乎是错误的,尽管它起作用了。


你解决了这个问题吗? - Douglas Gaskell
不,我仍在使用所描述的“解决方案”。 - Martina Grgić
2个回答

21

注意:根据您提供的链接,我假设您正在使用app.UseSpa()中间件。

路由中间件按顺序执行,如果请求找不到控制器,则返回404状态。 UseSpa中间件是万能的,任何到达该点的请求都将始终返回默认的SPA页面。这意味着任何尚未找到控制器的路由请求都将始终返回默认的SPA页面,并且不会抛出404错误。

您需要做的是仅在路由未以/api为前缀时才调用UseSpa()。这基本上允许任何以/api开头的请求跳过该点。

而不是:

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

使用:

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

这将允许以/api开头的任何请求通过此点,如果没有其他中间件或路由匹配,将返回404


3

感谢Douglas提供的精彩答案,我在此基础上进行了改进:

app.UseWhen( c => !c.Request.Path.StartsWithSegments( new PathString( "/api" ) ), app =>
    app.UseSpa( spa => {
        //[Snip]
    } ) );

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接