.net core 3.1 過濾器(Filter) 和AOP面向切面攔截器
Filter總共有五種,Authorization Filter,Resource Filter,Exception Filter,Action Filter,Result Filter
Exception Filter 設定
新增全域性異常過濾器GlobalExceptionFilter.cs,
當出現異常時進入此方法,可在這針對不同的異常做相關處理並返回指定資料,避免直接把錯誤暴露給使用者
public class GlobalExceptionFilter : IExceptionFilter { public void OnException(ExceptionContext context) { Exception ex= context.Exception; string errMsg = "GlobalExceptionFilter-OnException:" + ex.Message; if (context.Exception.GetType() == typeof(ExecuteException)) { //針對不同的自定義異常,做不同處理 MsgModel<string> msgModel = new MsgModel<string>() { Status= false, Msg = errMsg, Errcode = "AA001" }; context.Result = new JsonResult(msgModel); context.ExceptionHandled = true; } else { context.Result = new JsonResult(errMsg); context.ExceptionHandled = true; } LogHelper.Error(errMsg); } }
然後在Startup.cs 注入過濾器
Action Filter 設定
新增全域性過濾器GlobalActionFilter.cs
在方法執行前後,會跳轉至以下兩個方法,方便追蹤介面執行情況
public class GlobalActionFilter : IActionFilter { public void OnActionExecuted(ActionExecutedContext context) { //LogHelper.Info("OnActionExecuted"); //執行方法後執行這 } public void OnActionExecuting(ActionExecutingContext context) { //LogHelper.Info("OnActionExecuting"); //執行方法前先執行這 } }
Authonization Filter
許可權控制過濾器
通過 Authonization Filter 可以實現複雜的許可權角色認證
、登陸授權
等操作
/// <summary> /// 實現自定義授權 /// </summary> public class AuthorizeFilter : IAuthorizationFilter { /// <summary> /// 請求驗證,當前驗證部分不要丟擲異常,ExceptionFilter不會處理 /// </summary> /// <param name="context"></param> public void OnAuthorization(AuthorizationFilterContext context) {
//這裡可以做複雜的許可權控制操作
//if (context.HttpContext.User.Identity.Name != "1") //簡單的做一個示範
//{
// //未通過驗證則跳轉到無許可權提示頁
// RedirectToActionResult content = new RedirectToActionResult("NoAuth", "Exception", null);
// context.Result = content;
//
}
}
Resource Filter
資源過濾器
可以通過Resource Filter 進行資源快取
、防盜鏈
等操作。
使用Resource Filter 要求實現IResourceFilter 抽象介面
public class ResourceFilter : Attribute,IResourceFilter { public void OnResourceExecuted(ResourceExecutedContext context) { // 執行完後的操作 } public void OnResourceExecuting(ResourceExecutingContext context) { // 執行中的過濾器管道 } }
Result Filter
結果過濾器,可以對結果進行格式化、大小寫轉換等一系列操作。
使用Result Filter 需要實現IResultFilter 抽象介面,介面要求實現OnResultExecuting
方法 和OnResultExecuted
方法
OnResultExecuting
:Called before the action result executes. 在操作結果執行之前呼叫OnResultExecuted
:Called after the action result executes. 在操作結果執行之後呼叫
public class ResultFilter : Attribute, IResultFilter { public void OnResultExecuted(ResultExecutedContext context) { // 在結果執行之後呼叫的操作... } public void OnResultExecuting(ResultExecutingContext context) { // 在結果執行之前呼叫的一系列操作 } }
完畢 可以在全域性注入
AOP攔截器
LogInterceptor 設定
安裝Castle.Core,Autofac.Extras.DynamicProxy
新建LogInterceptor.cs ,繼承IInterceptor
public class LogInterceptor : IInterceptor { public void Intercept(IInvocation invocation) { try { invocation.Proceed(); Dapper.Logger.LogHelper.logger.Info(invocation.Method.Name); } catch (Exception ex) { Dapper.Logger.LogHelper.logger.Error(invocation.Method.Name + " " + ex.ToString()); } } }
在Startup.cs 新增以下程式碼
針對某個類或者某個方法做攔截時
首先新建一個攔截器MyInterceptor
public class MyInterceptor : IInterceptor { public void Intercept(IInvocation invocation) { try { invocation.Proceed(); NLogHelper.logger.Info(invocation.Method.Name); } catch (Exception ex) { NLogHelper.logger.Error(invocation.Method.Name + " " + ex.ToString()); } } }
然後Startup.cs 中ConfigureContainer程式碼如下
把LogInterceptor 程式碼註釋,但是要保留介面攔截EnableInterfaceInterceptors() ,注入MyInterceptor
public void ConfigureContainer(ContainerBuilder builder) { //builder.RegisterType<LogInterceptor>(); builder.RegisterType<MyInterceptor>(); builder.RegisterType<DbFactory>().As<IDbFactory>(); //業務邏輯層所在程式集名稱空間 Assembly service = Assembly.Load("Summer.Service"); //注:webapi要引用介面和類,不然這裡讀不到 //介面層所在程式集名稱空間 Assembly repository = Assembly.Load("Summer.IService"); //自動注入 builder.RegisterAssemblyTypes(service, repository) .Where(t => t.Name.EndsWith("Service")) .AsImplementedInterfaces() .InstancePerLifetimeScope() .EnableInterfaceInterceptors() //開啟介面攔截 //.InterceptedBy(typeof(LogInterceptor)) //設定全域性攔截器,統一由LogInterceptor攔截所有介面的呼叫 ; }
然後在需要攔截的介面中新增以下程式碼
攔截器設定完畢,當呼叫ITestService 的全部方法都會跳轉攔截器
Filter和LogInterceptor 可以同時共存,執行順序是:
ActionFilter 的OnActionExecuting =》LogInterceptor 的Intercept =》ActionFilter 的OnActionExecuted
如果介面有異常,不會跳轉LogInterceptor ,而是進入ExceptionFilter,順序是:
ActionFilter 的OnActionExecuting =》ActionFilter 的OnActionExecuted =》ExceptionFilter 的OnException