.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攔截器

其實好多項目中,做一些數據攔截、數據緩存都有Aop的概念,只是實現方式不一樣;之前大家可能都會利用過濾器來實現Aop的功能,如果是Asp.NetCore的話,也可能會使用中間件; 而這種實現方式都是在請求過程中進行攔截,如果我們想在服務層中做切面的話,那種方式顯然不好使了,需要用到“真正的Aop”。

 真正的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

原文 https://www.cnblogs.com/redo/p/12575119.html 

 

AOP的應用

引入三個包,通過Nuget安裝,Autofac開頭,如下

 

 注: 其中Autofac.Extras.DynamicProxy就是AOP相關組件,其中包含了Castle.Core,所以不用單獨安裝Castle.Core.

 

 

 

 

 

 

 

 

 

 

總結:

  AOP在做一些業務前置或后置處理上時很有用的,使用比較靈活,無需修改原有代碼邏輯,比起修改原有代碼維護相對好多啦!!!

 原文 https://www.cnblogs.com/zoe-zyq/p/12803450.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM