文章出處

在 ASP.NET Core 中,默認情況下當發生500或404錯誤時,只返回http狀態碼,不返回任何內容,頁面一片空白。

如果在 Startup.cs 的 Configure() 中加上 app.UseStatusCodePages(); ,500錯誤時依然是一片空白(不知為何對500錯誤不起作用),404錯誤時有所改觀,頁面會顯示下面的文字:

Status Code: 404; Not Found 

如果我們想實現不管500還是404錯誤都顯示自己定制的友好錯誤頁面,那該怎么辦呢?

對于500錯誤,我們可以用 app.UseExceptionHandler() 進行截獲;

對于404錯誤,我們可以用 app.UseStatusCodePages() 的增強版 app.UseStatusCodePagesWithReExecute() 進行截獲;

然后轉交給相應的URL進行處理。

app.UseExceptionHandler("/errors/500");
app.UseStatusCodePagesWithReExecute("/errors/{0}");

URL 路由到 MVC Controller 中顯示友好錯誤頁面。

public class ErrorsController : Controller
{
    [Route("errors/{statusCode}")]
    public IActionResult CustomError(int statusCode)
    {
        if(statusCode == 404)
        {
            return View("~/Views/Errors/404.cshtml");
        }
        return View("~/Views/Errors/500.cshtml");
    }        
}

【更新】

后來發現一個問題,當出現底層異常時,自定義錯誤頁面不能顯示,還是一片空白,比如下面的異常:

System.DllNotFoundException: Unable to load DLL 'System.Security.Cryptography.Native.Apple': The specified module could not be found.
 (Exception from HRESULT: 0x8007007E)

這時想到用 MVC 顯示自定義錯誤頁面的局限,如果發生的異常導致 MVC 本身不能正常工作,自定義錯誤頁面就無法顯示。

于是針對這個問題進行了改進,針對500錯誤直接用靜態文件的方式進行響應,Startup.cs 的 Configure() 中的代碼如下:

app.UseExceptionHandler(errorApp =>
{
    errorApp.Run(async context =>
    {
        context.Response.StatusCode = 500;
        if (context.Request.Headers["X-Requested-With"] != "XMLHttpRequest")
        {
            context.Response.ContentType = "text/html";
            await context.Response.SendFileAsync($@"{env.WebRootPath}/errors/500.html");
        }
    });
});
app.UseStatusCodePagesWithReExecute("/errors/{0}");

為了重用自定義錯誤頁面,MVC Controller 中已進行了修改:

public class ErrorsController : Controller
{
    private IHostingEnvironment _env;

    public ErrorsController(IHostingEnvironment env)
    {
        _env = env;
    }

    [Route("errors/{statusCode}")]
    public IActionResult CustomError(int statusCode)
    {
        var filePath = $"{_env.WebRootPath}/errors/{(statusCode == 404?404:500)}.html";
        return new PhysicalFileResult(filePath, new MediaTypeHeaderValue("text/html"));
    }        
}

文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()