ASP.NET Core中异常处理的几种方式

异常处理的集中方法:

  1. 配置HTTP错误代码页
  2. 使用MVC过滤器
  3. 异常捕获中间件

一、配置HTTP错误代码页

//在Startup.cs文件的Configure方法中添加如下代码
app.UseStatusCodePagesWithReExecute("/errors/{0}");
//创建Errors控制器返回指定错误页
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"));
    }
}

二、使用MVC过滤器

public class CustomerExceptionAttribute : ExceptionFilterAttribute
{
    private readonly IHostingEnvironment _hostingEnvironment;

    public CustomerExceptionAttribute(
        IHostingEnvironment hostingEnvironment)
    {
        _hostingEnvironment = hostingEnvironment;
    }

    public override void OnException(ExceptionContext filterContext)
    {
        if (!_hostingEnvironment.IsDevelopment())
        {
            return;
        }
        HttpRequest request = filterContext.HttpContext.Request;
        Exception exception = filterContext.Exception;
        //异常是否处理
        if (filterContext.ExceptionHandled == true)
        {
            return;
        }
        if (exception is UserFriendlyException)
        {
            //filterContext.Result = new ApplicationErrorResult
            filterContext.HttpContext.Response.StatusCode = 400;
            filterContext.HttpContext.Response.WriteAsync(exception.Message);
        }

        //下面进行异常处理的逻辑,可以记录日志、返回前端友好提示等
        //...

        //设置异常已经处理,否则会被其他异常过滤器覆盖
        filterContext.ExceptionHandled = true;
        //在派生类中重写时,获取或设置一个值,该值指定是否禁用IIS自定义错误。
        filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
    }
}

三、异常捕获中间件(Middleware)

使用MVC自带中间件

//在Startup.cs中添加如下代码
if (env.IsDevelopment())
{   //开发模式
    app.UseDeveloperExceptionPage();
}
else
{   //使用默认的异常处理
    //app.UseExceptionHandler();
    //使用自定义处理
    app.UseExceptionHandler(build =>
       build.Run(async context =>
       {
            var ex = context.Features.Get<Microsoft.AspNetCore.Diagnostics.IExceptionHandlerFeature>()?.Error;
            if (ex != null)
            {
                string innerException = String.Empty;
                while (ex.InnerException != null)
                {
                    ex = ex.InnerException;
                    innerException += ex.InnerException?.Message + "\r\n" + ex.InnerException?.StackTrace + "\r\n";
                }
                string message = $@"【{ex.Message}】内部错误【{ex.InnerException?.Message}】";
                //这里可以进行异常记录和针对异常做不同处理,我这里示例返回500
                context.Response.StatusCode = 500;
                context.Response.ContentType = "text/plain;charset=utf-8";
                await context.Response.WriteAsync("服务器变成蝴蝶飞走了!");
            }
            else
            {
                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");
                }
            }
        }
    ));
}

自定义中间件(可以进行日志记录)

public class ExceptionHandlerMiddleware
{
    private readonly RequestDelegate _next;

    public ExceptionHandlerMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        try
        {
            //这里也可以进行请求和响应日志的的记录
            await _next(context);
        }
        catch (Exception ex)
        {
            var statusCode = context.Response.StatusCode;
            //进行异常处理
        }
        finally
        {
            var statusCode = context.Response.StatusCode;
            var msg = String.Empty;
            switch (statusCode)
            {
                case 500:
                    msg = "服务器系统内部错误";
                    break;

                case 401:
                    msg = "未登录";
                    break;

                case 403:
                    msg = "无权限执行此操作";
                    break;

                case 408:
                    msg = "请求超时";
                    break;
            }
            if (!string.IsNullOrWhiteSpace(msg))
            {
                await HandleExceptionAsync(context, statusCode, msg);
            }
        }
    }
    private static Task HandleExceptionAsync(HttpContext context, int statusCode, string msg)
    {
        context.Response.ContentType = "application/json;charset=utf-8";
        context.Response.StatusCode = statusCode;
        return context.Response.WriteAsync(msg);
    }
}

参考文献:
Asp.Net Core异常处理
ASP.NET Core中显示自定义错误页面

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值