ASP.NET Coreにカスタムエラーページが表示されます

5730 ワード

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 Controlに友好エラーページが表示されます.
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 Controlで変更されました.
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"));
    }        
}