當未找到網頁並且應用程式返回 404 錯誤時,ASP.NET Core MVC 僅呈現通用瀏覽器錯誤頁面,如下圖所示
這不是很優雅,是嗎?
我們平時看到的404頁面一般是這樣的
還有這樣的
試了下京東,地址不存在的時候是會重定向到首頁
下面就來演示下ASP.NET Core中如何實現這種自定義的404頁面處理。
新建專案 ASP.NET Core MVC(WebApi處理方式也一樣)
新建好的專案直接執行的效果
隨便輸入一個地址 /test404
當未找到網頁並且應用程式返回 404 錯誤時,ASP.NET Core MVC 僅呈現通用瀏覽器錯誤頁面,如下圖所示
方式一 FallbackEndpointRouteBuilderExtensions.MapFallback
這是個什麼東西?
意思大概是說這是註冊一個優先順序最低的通配路由,來匹配所有路由,那就來試試效果吧。
// Program.cs
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.MapFallback(async (ctx) =>
{
ctx.Response.Body.Write(Encoding.UTF8.GetBytes("404 from Fallback"));
});
app.Run();
試試效果如下
方式二 自定義通配路由
在HomeController
新增一個Action如下
// HomeController.cs
[Route("{*url}", Order = 9999)]
public IActionResult Page404()
{
return View();
}
新增對應的View頁面如下
// Page404.cshtml
@{
ViewData["Title"] = "404";
}
<div>404 for {*url}</div>
效果圖
上面兩種方式雖然能夠正常處理404錯誤頁,但是在程式內部丟擲的404錯誤卻無法進行攔截
新增一個測試Action如下
[Route("/test404")]
public IActionResult test404()
{
// 一些業務處理,最終返回404
// return NotFound();
return StatusCode(404);
}
你看,這種404場景,上述方式沒能進行攔截處理。
方式三 自定義Middleware攔截
程式碼如下,關於Middleware如何使用這裡不做介紹
app.Use((context, next) =>
{
var res = next(context);
if (context.Response.StatusCode == 404)
{
context.Response.StatusCode = 200;
context.Response.Body.Write(Encoding.UTF8.GetBytes("404 from Middleware"));
}
return res;
});
把方式一和方式二的程式碼註釋掉,執行測試效果如下
不存在的地址
存在的地址,但是業務上返回404
方式四 UseStatusCodePagesWithReExecute
註釋上個方法的程式碼
app.UseStatusCodePagesWithReExecute("/error/{0}");
// HomeController.cs
[Route("test401")]
public IActionResult test401()
{
return StatusCode(401);
}
public class ErrorController : Controller
{
[Route("error/404", Order = 9)]
public IActionResult Error404()
{
ViewBag.code = 404;
return View();
}
[Route("error/{code:int}", Order = 1)]
public IActionResult Error(int code)
{
ViewBag.code = code;
switch (code)
{
case 404:
ViewBag.msg = "對不起,請求的資源不存在。";
break;
case 401:
ViewBag.msg = "對不起,您無許可權訪問此頁面。";
break;
default:
ViewBag.msg = "服務異常,請稍後重試!";
break;
}
return View("Error404");
}
}
// Error404.cshtml
@{
}
<div>@ViewBag.code : @ViewBag.msg</div>
測試效果
完美!!!!
方式五 web.config
<customErrors>
節點中配置ASP.NET管道處理404錯誤
這是以前framwork時代的iis配置方式,不推薦使用了,也不進行測試了。
總結
個人認為方式三、四推薦使用,四更加優雅,三是最靈活的,還有沒有其他方式進行攔截統一處理404錯誤呢,歡迎補充。