Popular blog tags

Global exception handling and log in ASP.NET core

Published

In this article, we are going to talk about Global exception handling and log in ASP.NET core

Error Handling with Try-Catch Block

Handling Errors Globally with the Built-In Middleware

Handling Errors Globally with the Custom Middleware

1.继承Controller,重写OnActionExecuted

新建controller时,默认都会继承一个Controller类,重写OnActionExecuted,添加上异常处理即可。一般情况下我们会新建一个BaseController, 让所有Controller继承BaseController。代码如下:

public class BaseController : Controller
{
    public override void OnActionExecuted(ActionExecutedContext context)
    {
        var exception = context.Exception;
        if (exception != null)
        {
            context.ExceptionHandled = true;
            context.Result = new ContentResult
            {
                Content = $"BaseController错误 : { exception.Message }"
            };
        }
        base.OnActionExecuted(context);
    }
}

缺点:

(1)如果cshtml页面抛错,就完全捕获不了。

(2)如果项目本身就是一个web api 项目,没有view,这还是可以的。

2.使用 ActionFilterAttribute

ActionFilterAttribute是一个特性,本身实现了 IActionFilter 及 IResultFilter , 所以不管是action里抛错,还是view里抛错,理论上都可以捕获。我们新建一个 ExceptionActionFilterAttribute, 重写 OnActionExecuted及OnResultExecuted,添加上异常处理,完整代码如下:

 

public class ExceptionActionFilterAttribute:ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext context)
    {
        var exception = context.Exception;
        if (exception != null)
        {
            context.ExceptionHandled = true;
            context.Result = new ContentResult
            {
                Content = $"错误 : { exception.Message }"
            };
        }
        base.OnActionExecuted(context);
    }

    public override void OnResultExecuted(ResultExecutedContext context)
    {
        var exception = context.Exception;
        if (exception != null)
        {
            context.ExceptionHandled = true;
            context.HttpContext.Response.WriteAsync($"错误 : {exception.Message}");
        }
        base.OnResultExecuted(context);
    }
}

使用方式有两种:

在controller里打上 [TypeFilter(typeof(ExceptionActionFilter)] 标签。
在Startup里以filter方式全局注入。

services.AddControllersWithViews(options =>
{
    options.Filters.Add<ExceptionActionFilterAttribute>();
})

 

3.使用 IExceptionFilter

Asp.Net Core提供了5类filter, IExceptionFilter是其中之一,顾名思义,这就是用来处理异常的。Asp.net Core中ExceptionFilterAttribute已经实现了IExceptionFilter,所以我们只需继承ExceptionFilterAttribute,重写其中方法即可。 同样新建CustomExceptionFilterAttribute继承 ExceptionFilterAttribute,重写 OnException ,添加异常处理,完整代码如下:

public class CustomExceptionFilterAttribute : ExceptionFilterAttribute
{
    public override void OnException(ExceptionContext context)
    {
        context.ExceptionHandled = true;
        context.HttpContext.Response.WriteAsync($"CustomExceptionFilterAttribute错误:{context.Exception.Message}");
        base.OnException(context);
    }
}

 

使用方式有两种,

在controller里打上 [CustomExceptionFilter] 标签。
在Startup里以filter方式全局注入。

services.AddControllersWithViews(options =>
{
    options.Filters.Add<CustomExceptionFilterAttribute>();
})

说明:

ExceptionFilterAttribute还提供了异步方法OnExceptionAsync,这两个处理方法,只需重写一个即可,如果两个都重写,两个方法都会执行一次。

4.使用系统自带ExceptionHandler中间件

在 startup 里,

if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseExceptionHandler("/Home/Error");
}

5.自定义Middleare处理

public class ErrorHandlingMiddleware
{
   private readonly RequestDelegate next;

   public ErrorHandlingMiddleware(RequestDelegate next)
   {
        this.next = next;
   }

   public async Task Invoke(HttpContext context)
   {
        try
        {
           await next(context);
        }
        catch (System.Exception ex)
        {
           //处理异常
        }
   }
}

 

 

1.http://stackoverflow.com/questions/28385889/global-exception-handling-in-asp-net-5

2.http://stackoverflow.com/questions/28967183/global-error-logging-in-asp-net-mvc-6?lq=1

3.http://stackoverflow.com/questions/28967183/global-error-logging-in-asp-net-mvc-6.