• ASP.NET Core中显示自定义错误页面


    在 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"));
        }        
    }
  • 相关阅读:
    由一段代码说开去——set
    由一段代码说开去——list
    day 11
    day 16
    day 10
    day 13
    day 9
    day 18
    day 12
    day 14
  • 原文地址:https://www.cnblogs.com/dudu/p/6004777.html
Copyright © 2020-2023  润新知