asp.net core mvc 对应着 .NET Framework 中的 ASP.NET MVC, 前者能够跨平台,可扩展,高性能,不过使人惊讶的是,虽然 ASP.NET Core 提供了大量的可选项能够完美的处理 404 错误,但 ASP.NET Core MVC 在默认状况下并无选择它们,你说奇怪不?
这就形成了当请求一个不存在的页面时,应用程序将会返回一个 404 错误,ASP.NET Core MVC 目前会展现一个浏览器通用的错误页,以下图所示:html
这篇文章我准备讨论 3种 方式来优雅的处理这种 404 错误。web
接下来我会在 Visual Studio 2019 中建立一个 ASP.NET Core MVC 项目,用这个项目去展现如何处理 404 错误。浏览器
而后把 ASP.NET Core MVC 项目跑起来,你会看到应用程序默认的首页,上面还带一行 welcome 的欢迎语?,以下图所示:mvc
接下来咱们尝试在浏览器中输入一个不存在的网址,好比说:http://localhost:6440/welcome, 这时候 ASP.NET Core MVC 引擎将会访问这个地址的资源,可想而知,引擎确定会返回一个 404 错误,你也会看到以下错误页,一般状况下这是很是让人难堪的,对吧。app
有几种方式能够比较完美的处理这种默认的 404 错误,一个简单的方案就是去检查 response 的 http 状态码,一旦发现这个 status = 404,你能够重定向到一个web 中存在的页面或者一个特定的错误页,下面的代码展现了,你能够在 Startup.Configure 方法中进行全局判断,一旦发现404错误就导向 home 页面。asp.net
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 页面。async
下面是 Configure 方法的完整代码。ide
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?}"); }); }
第二种可选的解决方案是,采用 ASP.NET Core 中内置的 UseStatusCodePages 中间件,下面的代码展现了如何在 Startup.Configure 方法中去实现 StatusCodePages 。性能
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseStatusCodePages(); //Other code }
如今你能够把程序跑起来而后浏览一下这个不存在的资源,下图展现了这种状况下的输出结果:ui
你能够利用 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,好比说,你能够建立 Home/Error/500.cshtml 或者 Home/Error/404.cshtml 视图,而后根据 http status code 的值重定向到合适的错误页。
另一种处理 404 错误的方式是使用一个自定义的页面,而后在页面上设置一些特定的错误代码,这样也方便隐藏一些比较重要的信息,好比将 404 改为 服务压力大,请联系管理员 等等,一旦应用程序发生错误,你能够将用户导向你设置的错误页,而后展现你设置的错误信息。