[ASP.NET Web API 2] Global Error Handler - 實作 ExceptionFilterAttribute 捕捉應用程式例外並紀錄請求參數

Global Error Handler 有很多的方式,這次來介紹 System.Web.Http.Filters.ExceptionFilterAttribute,用它集中管理應用程式的例外,不需要在每一個動作包裝錯誤,你可以針對不同的例外進行處理,比如,有專門的 Filter 處理交易例外

開發環境

  • VS 2019
  • .NET Framework 4.8
  • NLog 4.7.3

實作

開一個 Web API 的專案,

  • 安裝 NLog.Config,這樣相依的套件也會一併安裝}
    Install-Package NLog.Config
  • 實作 ExceptionFilterAttribute。
  • 覆寫 OnException 方法。
  • 很輕易的可以從 actionContext,拿到 ControllerName、ActionName、ActionArguments,拿到之後就看你要怎麼紀錄 Log。
  • 當註冊多個 Exception Filter,拋出 HttpResponseException 就可以結束 Exception Filter 的 Pipeline,接下來的 Exception Filter 就不會執行了。

代碼如下:

public class ErrorHandlerAttribute : ExceptionFilterAttribute
{
    public override void OnException(HttpActionExecutedContext actionContext)
    {
        var exception = actionContext.Exception;
        if (exception == null)
        {
            return;
        }
 
        var controllerName = actionContext.ActionContext
                                          .ControllerContext
                                          .ControllerDescriptor
                                          .ControllerName;
 
        var actionName      = actionContext.ActionContext.ActionDescriptor.ActionName;
        var actionArguments = actionContext.ActionContext.ActionArguments;
        var url             = actionContext.Request.RequestUri.ToString();
        var error = new
        {
            Url             = url,
            ControllerName  = controllerName,
            ActionName      = actionName,
            ActionArguments = actionArguments,
        };
        var logger = LogManager.GetLogger($"{controllerName}.{actionName}");
 
        logger.Error(exception, JsonConvert.SerializeObject(error));
        actionContext.Response = actionContext.Request
                                              .CreateResponse(HttpStatusCode.InternalServerError, error);
 
        // 結束 Exception Filter
        throw new HttpResponseException(actionContext.Response);
    }
}

 

接著在 Action 故意引發例外

public class ValuesController : ApiController
{
    public void Post(Employee request)
    {
        throw new Exception("GG~");
    }
}
 
public class Employee
{
    public int Id { get; set; }
 
    public string Name { get; set; }
}

 

接著 Ctrl + F5 運行網站,用 Postman 打的效果如下圖:

 

範例位置

https://github.com/yaochangyu/sample.dotblog/tree/master/WebAPI/Lab.Global%20ErrorHandler

若有謬誤,煩請告知,新手發帖請多包涵


Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET

Image result for microsoft+mvp+logo