[料理佳餚] 在 ASP.NET Core MVC 自訂 HTTP 狀態碼頁面

商業網站通常都會自訂自己的 HTTP 狀態碼頁面,先前有寫兩篇文章介紹在 ASP.NET MVC 如何來做這件事?

現在環境換到了 ASP.NET Core,我們來看一下怎麼處理自訂 HTTP 狀態碼頁面?

傳統的 ASP.NET MVC 幾乎都是寄宿在 IIS 上,所以要自訂 HTTP 狀態碼頁面,在 Web.Config 就要在兩個區塊上做設定,一個是 <system.web>/<customErrors>,一個是 <system.webServer>/<httpErrors>,但是換到了 ASP.NET Core 就不用了。

內部轉發(ReExecute)或轉址(Redirect)

自訂 HTTP 狀態碼頁面一般有兩種處理方式,一種是內部轉發(ReExecute),一種是轉址(Redirect),差別只在於內部轉發,其瀏覽器的網址不會變,我都是用內部轉發比較多,但是會留有 HTTP 狀態碼頁面的對外網址,方便前端程式可以自行轉址。

自訂內部轉發 HTTP 狀態碼頁面

首先,我們需要產生幾個 HTTP 狀態碼頁面,我就用 ASP.NET Core MVC 的專案範本來建立一個 Web 應用程式,在 HomeController 新增 StatusCodePage 的 Action,然後針對 400、403、404、500 回應自訂的 View,其他狀態碼則回應一段純文字。

public class HomeController : Controller
{
    // ...

    public IActionResult StatusCodePage(int id)
    {
        switch (id)
        {
            case 400: return new ViewResult { ViewName = "BadRequest", ViewData = this.ViewData, TempData = this.TempData, StatusCode = id };
            case 404: return new ViewResult { ViewName = "NotFound", ViewData = this.ViewData, TempData = this.TempData, StatusCode = id };
            case 403: return new ViewResult { ViewName = "Forbidden", ViewData = this.ViewData, TempData = this.TempData, StatusCode = id };
            case 500: return new ViewResult { ViewName = "InternalServerError", ViewData = this.ViewData, TempData = this.TempData, StatusCode = id };
            default: return new ContentResult { Content = $"{id} - {(HttpStatusCode)id}", StatusCode = id };
        }
    }
}

接著,到 Startup.csConfigure() 方法內,加入下面這一段程式碼:

這樣就好了,只要我們回應的 Result 狀態碼是 400 ~ 599 之間,而且沒有塞回應內容,這些都會被 StatusCodePages Middleware 給攔截,最後我寫了一個 TestStatusCodePage 的 Action,回傳 StatusCodeResult 來測試自訂 HTTP 狀態碼頁面。

有一件事要記得,我們需要把執行環境改成 Production 或 Staging,這樣我們在 Startup.cs 裡面加的程式碼才會正常運作。

相關資源

C# 指南
ASP.NET 教學
ASP.NET MVC 指引
Azure SQL Database 教學
SQL Server 教學
Xamarin.Forms 教學