统一处理 ASP.NET Core 中的 404 错误异常信息
admin
2021-06-03本文作者:梁桐铭- 微软最有价值专家(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 与我们的应用程序中的所有路由都不匹配,引发的错误。
处理不成功的 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
,它会返回以下简单的文本响应。
请注意: 要触发此异常,请修改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 错误信息。
到现在为止我们还有一个中间件没有讲,那就是 UseStatusCodePagesWithReExecute。
我们将 Configure()方法中的
app.UseStatusCodePagesWithRedirects("/Error/{0}");
替换为
app.UseStatusCodePagesWithReExecute("/Error/{0}");
重新运行应用程序并导航到http://localhost/market/food
,我们看到 在 NotFound.cshtml 视图中同样触发了相同的自定义 404 错误信息。
在这一点上我们想到的一个显而易见的问题是,这两个中间件组件之间的区别是什么,我们应该使用哪一个。
在下个章节中,我们来对比下他们的不同
文章说明
如果您觉得我的文章质量还不错,欢迎打赏,也可以订阅我的视频哦
未得到授权不得擅自转载本文内容,52abp.com 保留版权
感谢您对我的支持
关注微信公众号:角落的白板报