1. 程式人生 > 實用技巧 >題解 Gym101889J 【Jumping frog】

題解 Gym101889J 【Jumping frog】

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