如何在 ASP.NET Core 中处理 404 错误

asp.net core mvc 对应着 .NET Framework 中的 ASP.NET MVC, 前者可以跨平台 , 可扩展 , 高性能 , 不过令人惊讶的是 , 虽然 ASP.NET Core 提供了大量的可选项可以完美的处理 404 错误 , 但 ASP.NET Core MVC 在默认情况下并没有选择它们 , 你说奇怪不?
这就造成了当请求一个不存在的页面时 , 应用程序将会返回一个 404 错误 , ASP.NET Core MVC 目前会展示一个浏览器通用的错误页 , 如下图所示:

如何在 ASP.NET Core 中处理 404 错误

文章插图
这篇文章我准备讨论 3种 方式来优雅的处理这种 404 错误 。
接下来我会在 Visual Studio 2019 中创建一个 ASP.NET Core MVC 项目 , 用这个项目去展示如何处理 404 错误 。
然后把 ASP.NET Core MVC 项目跑起来 , 你会看到应用程序默认的首页 , 上面还带一行 welcome 的欢迎语 , 如下图所示:
如何在 ASP.NET Core 中处理 404 错误

文章插图
接下来我们尝试在浏览器中输入一个不存在的网址 , 比如说:http://localhost:6440/welcome, 这时候 ASP.NET Core MVC 引擎将会访问这个地址的资源 , 可想而知 , 引擎肯定会返回一个 404 错误 , 你也会看到如下错误页 , 通常情况下这是非常让人难堪的 , 对吧 。
如何在 ASP.NET Core 中处理 404 错误

文章插图
检查 ASP.NET Core MVC 的 Response.StatusCode有几种方式可以比较完美的处理这种默认的 404 错误 , 一个简单的方案就是去检查 response 的 http 状态码 , 一旦发现这个 status = 404 , 你可以重定向到一个web 中存在的页面或者一个特定的错误页 , 下面的代码展示了 , 你可以在 Startup.Configure 方法中进行全局判断 , 一旦发现404错误就导向 home 页面 。
public class Startup{public void Configure(IApplicationBuilder app, IWebHostEnvironment env){app.Use(async (context, next) =>{await next();if (context.Response.StatusCode == 404){context.Request.Path = "/Home";await next();}});}}接下来运行web程序 , 然后键入 http://localhost:6440/welcome,你会发现最终展示了 home 页面 。
下面是 Configure 方法的完整代码 。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env){if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}else{app.UseExceptionHandler("/Home/Error");}app.Use(async (context, next) =>{await next();if (context.Response.StatusCode == 404){context.Request.Path = "/Home";await next();}});app.UseStaticFiles();app.UseRouting();app.UseAuthorization();app.UseEndpoints(endpoints =>{endpoints.MapControllerRoute(name: "default",pattern: "{controller=Home}/{action=Index}/{id?}");});}使用 UseStatusCodePages 中间件第二种可选的解决方案是 , 采用 ASP.NET Core 中内置的 UseStatusCodePages 中间件 , 下面的代码展示了如何在 Startup.Configure 方法中去实现 StatusCodePages。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env){app.UseStatusCodePages();//Other code}现在你可以把程序跑起来然后浏览一下这个不存在的资源 , 下图展示了这种情况下的输出结果:
如何在 ASP.NET Core 中处理 404 错误

文章插图
使用 UseStatusCodePagesWithReExecute 中间件你可以利用 UseStatusCodePagesWithReExecute 中间件来处理 那种 Response 还没开始构建 就遇到的一些不成功的状态 , 有点绕哈 , 因此这个中间件不会处理 Response status 等于 404 的情况 , 当 404 发生的时候 , 这个中间件要做的就是将 request 重定向到另外一个 Action 去处理这个错误 。
下面的代码展示了如何使用这个中间件将 request 重定向到另外一个 action 方法 。
app.UseStatusCodePagesWithReExecute("/Home/HandleError/{0}");然后再来看一下被重定向的 Action 方法 。
[Route("/Home/HandleError/{code:int}")]public IActionResult HandleError(int code){ViewData["ErrorMessage"] = $"Error occurred. The ErrorCode is: {code}";return View("~/Views/Shared/HandleError.cshtml");}现在我把展示错误信息的 HandleError 视图的创建留给你去实现吧!
最后 , 你可能想为一些错误码创建一些特定的view , 比如说 , 你可以创建 


推荐阅读