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