统一处理 ASP.NET Core 中的 404 错误异常信息

Author Image
admin Tuesday, November 17, 2020 阅读数: 32
Share:

本文作者:梁桐铭- 微软最有价值专家(Microsoft MVP)
本文出自《从零开始学 ASP.NET Core 与 EntityFramework Core》目录
视频课程效果更佳:跨平台开发实战掌握 ASP.NET Core 与 EntityFramework Core

统一处理 ASP.NET Core 中的 404 错误异常信息

在本章节中,我们将学习如何在 ASP.NET Core 中统一处理 404 错误,即 Page Not Found 错误。 在此过程中,我们将学习以下 3 个中间件组件,这些组件的作用是处理 ASP.NET Core 中的状态代码页。

  • UseStatusCodePages
  • UseStatusCodePagesWithRedirects
  • UseStatusCodePagesWithReExecute

404 错误的类型

在 ASP.NET Core 中,有两种类型的 404 错误可能发生:

类型 1:找不到指定 ID 的资源信息。关于如何处理这种类型的 404 错误,让它合理,我们在前面的章节已经介绍了,如何制作自定义的错误视图。

类型 2:请求的 URL 地址和路由不匹配。在本章节中,我们将学习如何统一方式处理此类 404 错误。

ASP.NET Core 中的 404 错误示例

以下是 Startup.cs 文件中 Startup 类的 Configure()方法中的代码。您可能已经知道,这个 Configure() 方法是用于配置 ASP.NET Core 应用程序的 HTTP 请求处理管道。


public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseStaticFiles();

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


ASP.NET Core 中的默认 404 错误异常页面

目前,我们在此 http 请求处理管道中没有配置任何处理 404 错误的内容。因此,如果我们导航到 http://localhost/market/food,我们会看到以下默认的 404 错误页面。这是因为 URL/market/food 与我们的应用程序中的所有路由都不匹配,引发的错误。

error

处理不成功的 http 状态代码

为了处理不成功的 http 状态代码,例如 404,我们可以使用以下 3 个内置的 ASP.NET Core 中间件组件。

  • UseStatusCodePages
  • UseStatusCodePagesWithRedirects
  • UseStatusCodePagesWithReExecute

UseStatusCodePages 中间件

个人认为这是 3 个状态码中间件组件中最不实用的。因为这个原因,我们很少在现实世界的生产应用程序中使用它。要在应用程序中使用它并查看它可以执行的操作,请将其插入 http 处理管道,如下所示。

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseStatusCodePages();
    }

    app.UseStaticFiles();

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


因为添加了 UseStatusCodePages 中间件,如果我们浏览到http://localhost/market/food,它会返回以下简单的文本响应。

404error

请注意: 要触发此异常,请修改launchSettings.json中的环境变量为非Development,如Staging,否则无法触发该异常。

UseStatusCodePagesWithRedirects 中间件

在生产应用程序中,我们希望拦截这些不成功的 http 状态代码并返回自定义错误视图。为此,我们可以使用UseStatusCodePagesWithRedirects中间件或UseStatusCodePagesWithReExecute中间件。

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseStatusCodePagesWithRedirects("/Error/{0}");
    }

    app.UseStaticFiles();

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

我们添加了下面的代码到 Configure()方法中,如果出现 404 错误的时候,则会将用户重定向到/Error/404。这里我们采用了占位符**{0}** ,它会自动接收 HTTP 中的状态代码。

  app.UseStatusCodePagesWithRedirects("/Error/{0}");

添加 ErrorController

要统一显示错误信息,我们需要添加对应的控制器和视图代码,请参考以下代码:


public class ErrorController : Controller
{
   //如果状态代码为404,则路径将变为Error/404
    [Route("Error/{statusCode}")]
    public IActionResult HttpStatusCodeHandler(int statusCode)
    {
        switch (statusCode)
        {
            case 404:
                ViewBag.ErrorMessage = "抱歉,你访问的页面不存在";
                break;
        }

        return View("NotFound");
    }
}

添加 NotFound 视图


@{
ViewBag.Title = "页面不存在";
}

<h1>@ViewBag.ErrorMessage</h1>

<a asp-action="index" asp-controller="home">
   点击此处返回首页
</a>

此时,如果我们导航到http://localhost/market/food,我们会看到以下页面已经被导航到了 NotFound.cshtml 页面,显示自定义 404 错误信息。

58-3

到现在为止我们还有一个中间件没有讲,那就是 UseStatusCodePagesWithReExecute。

我们将 Configure()方法中的

  app.UseStatusCodePagesWithRedirects("/Error/{0}");

替换为

app.UseStatusCodePagesWithReExecute("/Error/{0}");

重新运行应用程序并导航到http://localhost/market/food,我们看到 在 NotFound.cshtml 视图中同样触发了相同的自定义 404 错误信息。

在这一点上我们想到的一个显而易见的问题是,这两个中间件组件之间的区别是什么,我们应该使用哪一个。

在下个章节中,我们来对比下他们的不同

文章说明

如果您觉得我的文章质量还不错,欢迎打赏,也可以订阅我的视频哦
未得到授权不得擅自转载本文内容,52abp.com 保留版权
感谢您对我的支持

关注微信公众号:角落的白板报

公众号:角落的白板报