主頁 > .NET開發 > Asp.Net Core Filter 深入淺出的那些事-AOP

Asp.Net Core Filter 深入淺出的那些事-AOP

2020-09-16 20:36:06 .NET開發

一、前言

在分享ASP.NET Core Filter 使用之前,先來談談AOP,什么是AOP 呢?

AOP全稱Aspect Oriented Programming意為面向切面編程,也叫做面向方法編程,是通過預編譯方式和運行期動態代理的方式實作不修改源代碼的情況下給程式動態統一添加功能的技術,

AOP技術利用一種稱為“橫切”的技術,剖解開封裝物件的內部,將影響多個類的公共行為封裝到一個可重用的模塊中,并將其命名為Aspect切面,所謂的切面,簡單來說就是與業務無關,卻為業務模塊所共同呼叫的邏輯,將其封裝起來便于減少系統的重復代碼,降低模塊的耦合度,有利用未來的可操作性和可維護性,

利用AOP可以對業務邏輯各個部分進行隔離,從而使業務邏輯各部分之間的耦合度降低,提高程式的可重用性,同時提高開發效率,

AOP的使用場景主要包括日志記錄、性能統計、安全控制、事務處理、例外處理等,

二、Filter-過濾器

Filter是延續ASP.NET MVC的產物,同樣保留了五種的Filter,分別是Authorization Filter、Resource Filter、Action Filter、Exception Filter及Result Filter,
通過不同的Filter可以有效處理封包進出的加工,本篇將介紹ASP.NET Core的五種Filter運作方式,

2.1 Filter 介紹

ASP.NET Core 有以下五種Filter 可以使用:

  • Authorization Filter:
    Authorization是五種Filter中優先級最高的,通常用于驗證Request合不合法,不合法后面就直接跳過,
  • Resource Filter:Resource是第二優先,會在Authorization之后,Model Binding之前執行,通常會是需要對Model加工處理才用,
  • Exception Filter:例外處理的Filter,
  • Action Filter:最常使用的Filter,封包進出都會經過它,使用上沒什么需要特別注意的,跟Resource Filter很類似,但并不會經過Model Binding,
  • Result Filter:當Action完成后,最侄訓經過的Filter,

三、五大Filter 的應用

這一篇章主要來講解Asp.Net Core 的五大過濾器的實作及用途.

3.1 Authonization Filter

權限控制過濾器
通過 Authonization Filter 可以實作復雜的權限角色認證登陸授權等操作
實作事例代碼如下:

    public class AuthonizationFilter :Attribute,IAuthorizationFilter
    {
        public void OnAuthorization(AuthorizationFilterContext context)
        {
            //這里可以做復雜的權限控制操作
            if (context.HttpContext.User.Identity.Name != "1") //簡單的做一個示范
            {
                //未通過驗證則跳轉到無權限提示頁
                RedirectToActionResult content = new RedirectToActionResult("NoAuth", "Exception", null);
                context.Result = content;
            }
        }
    }

3.2 Resource Filter

資源過濾器
可以通過Resource Filter 進行資源快取防盜鏈等操作,
使用Resource Filter 要求實作IResourceFilter 抽象介面

   public class ResourceFilter : Attribute,IResourceFilter
    {
        public void OnResourceExecuted(ResourceExecutedContext context)
        {
            // 執行完后的操作
        }

        public void OnResourceExecuting(ResourceExecutingContext context)
        {
            // 執行中的過濾器管道
        }
    }

3.3 Exception Filter

通過Execption Filter 過濾器可以進行全域的例外日志收集 等操作,

使用Execption Filter 要求實作IExceptionFilter 抽象介面
IExceptionFilter介面會要求實作OnException方法,當系統發生未捕獲例外時就會觸發這個方法,OnException方法有一個ExceptionContext例外背景關系,其中包含了具體的例外資訊,HttpContext及mvc路由資訊,系統一旦出現未捕獲例外后,比較常見的做法就是使用日志工具,將例外的詳細資訊記錄下來,方便修正除錯,下面是日志記錄的實作,  

  public class ExecptionFilter : Attribute, IExceptionFilter
  {
        private ILogger<ExecptionFilter> _logger;
        //構造注入日志組件
        public ExecptionFilter(ILogger<ExecptionFilter> logger)
        {
            _logger = logger;
        }

        public void OnException(ExceptionContext context)
        {
            //日志收集
            _logger.LogError(context.Exception, context?.Exception?.Message??"例外");
        }
    }

3.4 Action Filter

作用:可以通過ActionFilter 攔截 每個執行的方法進行一系列的操作,比如:執行操作日志引數驗證權限控制 等一系列操作,

使用Action Filter 需要實作IActionFilter 抽象介面,IActionFilter 介面要求實作OnActionExecutedOnActionExecuting 方法

    public class ActionFilter : Attribute, IActionFilter
    {
        public void OnActionExecuted(ActionExecutedContext context)
        {
            //執行完成....
        }

        public void OnActionExecuting(ActionExecutingContext context)
        {
            //執行中...
        }
    }

3.5 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)
        {
            // 在結果執行之前呼叫的一系列操作
        }
    }

四、Asp.Net Core 過濾器的注冊方式

這一篇章主要來分析探討Asp.Net Core 中過濾器的三種注冊方式ActionController全域

4.1 Action 注冊方式

Action 注冊方式是區域注冊方式,針對控制器中的某個方法上標注特性的方式進行注冊,代碼如下:

 [AuthonizationFilter()]
 public IActionResult Index()
 {
            return View();
 }

4.2 Controller 注冊方式

了解過Action 特性注冊方式的同學,一定發現了它的不好之處就是我一個控制器里面需要使用同一套Filter 的時候,需要一個一個Action 標注特性注冊,是不是很繁瑣呢?有沒有其他方式進行代替這些繁瑣的操作呢?微軟給我們提供了簡便的控制器標注注冊方式,代碼如下:

 [AuthonizationFilter()]
 public class FirstController : Controller
  {
        private ILogger<FirstController> _logger;

        public FirstController(ILogger<FirstController> logger)
        {
            _logger = logger;
        }

        public IActionResult Index()
        {
            return View();
        }
 }

4.3 全域注冊方式

現在有些同學考慮了一些全域的情況,比如我要全域處理系統中的例外,或者收集操作日志等,需要全域注冊一個ExceptionFilter 來實作,就不需要每一個Controller 中進行代碼注冊,方便快捷,代碼如下:

 public void ConfigureServices(IServiceCollection services)
  {
            //全域注冊例外過濾器
            services.AddControllersWithViews(option=> {
                option.Filters.Add<ExecptionFilter>();
            });

            services.AddSingleton<ISingletonService, SingletonService>();
}

4.4 TypeFilter 和 ServiceFilter 注冊方式

上面的五大過濾器中事例代碼中其中有一個過濾器的代碼比較特,再來回顧ExceptionFilter過濾器的實作代碼:

    public class ExecptionFilter : Attribute, IExceptionFilter
    {
        private ILogger<ExecptionFilter> _logger;
        //構造注入日志組件
        public ExecptionFilter(ILogger<ExecptionFilter> logger)
        {
            _logger = logger;
        }

        public void OnException(ExceptionContext context)
        {
            //日志收集
            _logger.LogError(context.Exception, context?.Exception?.Message??"例外");
        }
    }

從上面的代碼中可以發現 ExceptionFilter 過濾器實作中存在日志服務的建構式的注入,也就是說該過濾器依賴于其他的日志服務,但是日志服務都是通過DI 注入進來的;再來回顧下上面Action 注冊方式或者Controller 注冊方式 也即Attribute 特性標注注冊方式,本身基礎的特性是不支持建構式的,是在運行時注冊進來的,那要解決這種本身需要對服務依賴的過濾器需要使用 TypeFilter 或者ServiceFilter 方式進行過濾器的標注注冊,

TypeFilterServiceFilter 的區別,

  • ServiceFilter和TypeFilter都實作了IFilterFactory
  • ServiceFilter需要對自定義的Filter進行注冊,TypeFilter不需要
  • ServiceFilter的Filter生命周期源自于您如何注冊,而TypeFilter每次都會創建一個新的實體

TypeFilter 使用方式

代碼如下:

[TypeFilter(typeof(ExecptionFilter))]
public IActionFilter Index2()
{
      return View();
}

通過上面的代碼可以發現AuthonizationFilter 是默認的構造器,但是如果過濾器中建構式中存在引數,需要注入服務那該怎么辦呢?,比如上面的ExceptionFilter 代碼,就不能使用這種方式進行注冊,需要使用服務特性的方式,我們可以選擇使用 代碼如下:

[TypeFilter(typeof(ExecptionFilter))]
public IActionFilter Index2()
{
           return View();
}

ServiceFilter 使用方式

控制器中的代碼如下:

[ServiceFilter(typeof(ExecptionFilter))]
public IActionFilter Index2()
{
           return View();
}

注冊服務的代碼如下:

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
       Console.WriteLine("ConfigureServices");
       services.AddControllersWithViews();

       //services.AddControllersWithViews(option=> {
       //    option.Filters.Add<ExecptionFilter>();
       //});
        
        //注冊過濾器服務,使用ServiceFilter 方式必須要注冊 否則會報沒有注冊該服務的相關例外
        services.AddSingleton<ExecptionFilter>();
}

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/59647.html

標籤:.NET Core

上一篇:學習服務之間的呼叫,三個方法的演化

下一篇:[Abp vNext 原始碼分析] - 19. 多租戶

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • WebAPI簡介

    Web體系結構: 有三個核心:資源(resource),URL(統一資源識別符號)和表示 他們的關系是這樣的:一個資源由一個URL進行標識,HTTP客戶端使用URL定位資源,表示是從資源回傳資料,媒體型別是資源回傳的資料格式。 接下來我們說下HTTP. HTTP協議的系統是一種無狀態的方式,使用請求/ ......

    uj5u.com 2020-09-09 22:07:47 more
  • asp.net core 3.1 入口:Program.cs中的Main函式

    本文分析Program.cs 中Main()函式中代碼的運行順序分析asp.net core程式的啟動,重點不是剖析原始碼,而是理清程式開始時執行的順序。到呼叫了哪些實體,哪些法方。asp.net core 3.1 的程式入口在專案Program.cs檔案里,如下。ususing System; us ......

    uj5u.com 2020-09-09 22:07:49 more
  • asp.net網站作為websocket服務端的應用該如何寫

    最近被websocket的一個問題困擾了很久,有一個需求是在web網站中搭建websocket服務。客戶端通過網頁與服務器建立連接,然后服務器根據ip給客戶端網頁發送資訊。 其實,這個需求并不難,只是剛開始對websocket的內容不太了解。上網搜索了一下,有通過asp.net core 實作的、有 ......

    uj5u.com 2020-09-09 22:08:02 more
  • ASP.NET 開源匯入匯出庫Magicodes.IE Docker中使用

    Magicodes.IE在Docker中使用 更新歷史 2019.02.13 【Nuget】版本更新到2.0.2 【匯入】修復單列匯入的Bug,單元測驗“OneColumnImporter_Test”。問題見(https://github.com/dotnetcore/Magicodes.IE/is ......

    uj5u.com 2020-09-09 22:08:05 more
  • 在webform中使用ajax

    如果你用過Asp.net webform, 說明你也算是.NET 開發的老兵了。WEBform應該是2011 2013左右,當時還用visual studio 2005、 visual studio 2008。后來基本都用的是MVC。 如果是新開發的專案,估計沒人會用webform技術。但是有些舊版 ......

    uj5u.com 2020-09-09 22:08:50 more
  • iis添加asp.net網站,訪問提示:由于擴展配置問題而無法提供您請求的

    今天在iis服務器配置asp.net網站,遇到一個問題,記錄一下: 問題:由于擴展配置問題而無法提供您請求的頁面。如果該頁面是腳本,請添加處理程式。如果應下載檔案,請添加 MIME 映射。 WindowServer2012服務器,添加角色安裝完.netframework和iis之后,運行aspx頁面 ......

    uj5u.com 2020-09-09 22:10:00 more
  • WebAPI-處理架構

    帶著問題去思考,大家好! 問題1:HTTP請求和回傳相應的HTTP回應資訊之間發生了什么? 1:首先是最底層,托管層,位于WebAPI和底層HTTP堆疊之間 2:其次是 訊息處理程式管道層,這里比如日志和快取。OWIN的參考是將訊息處理程式管道的一些功能下移到堆疊下端的OWIN中間件了。 3:控制器處理 ......

    uj5u.com 2020-09-09 22:11:13 more
  • 微信門戶開發框架-使用指導說明書

    微信門戶應用管理系統,采用基于 MVC + Bootstrap + Ajax + Enterprise Library的技術路線,界面層采用Boostrap + Metronic組合的前端框架,資料訪問層支持Oracle、SQLServer、MySQL、PostgreSQL等資料庫。框架以MVC5,... ......

    uj5u.com 2020-09-09 22:15:18 more
  • WebAPI-HTTP編程模型

    帶著問題去思考,大家好!它是什么?它包含什么?它能干什么? 訊息 HTTP編程模型的核心就是訊息抽象,表示為:HttPRequestMessage,HttpResponseMessage.用于客戶端和服務端之間交換請求和回應訊息。 HttpMethod類包含了一組靜態屬性: private stat ......

    uj5u.com 2020-09-09 22:15:23 more
  • 部署WebApi隨筆

    一、跨域 NuGet參考Microsoft.AspNet.WebApi.Cors WebApiConfig.cs中配置: // Web API 配置和服務 config.EnableCors(new EnableCorsAttribute("*", "*", "*")); 二、清除默認回傳XML格式 ......

    uj5u.com 2020-09-09 22:15:48 more
最新发布
  • C#多執行緒學習(二) 如何操縱一個執行緒

    <a href="https://www.cnblogs.com/x-zhi/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2943582/20220801082530.png" alt="" /></...

    uj5u.com 2023-04-19 09:17:20 more
  • C#多執行緒學習(二) 如何操縱一個執行緒

    C#多執行緒學習(二) 如何操縱一個執行緒 執行緒學習第一篇:C#多執行緒學習(一) 多執行緒的相關概念 下面我們就動手來創建一個執行緒,使用Thread類創建執行緒時,只需提供執行緒入口即可。(執行緒入口使程式知道該讓這個執行緒干什么事) 在C#中,執行緒入口是通過ThreadStart代理(delegate)來提供的 ......

    uj5u.com 2023-04-19 09:16:49 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    <a href="https://www.cnblogs.com/huangxincheng/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/214741/20200614104537.png" alt="" /&g...

    uj5u.com 2023-04-18 08:39:04 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    一:背景 1. 講故事 前段時間協助訓練營里的一位朋友分析了一個程式卡死的問題,回過頭來看這個案例比較經典,這篇稍微整理一下供后來者少踩坑吧。 二:WinDbg 分析 1. 為什么會卡死 因為是表單程式,理所當然就是看主執行緒此時正在做什么? 可以用 ~0s ; k 看一下便知。 0:000> k # ......

    uj5u.com 2023-04-18 08:33:10 more
  • SignalR, No Connection with that ID,IIS

    <a href="https://www.cnblogs.com/smartstar/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/u36196.jpg" alt="" /></a>...

    uj5u.com 2023-03-30 17:21:52 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:15:33 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:13:31 more
  • C#遍歷指定檔案夾中所有檔案的3種方法

    <a href="https://www.cnblogs.com/xbhp/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/957602/20230310105611.png" alt="" /></a&...

    uj5u.com 2023-03-27 14:46:55 more
  • C#/VB.NET:如何將PDF轉為PDF/A

    <a href="https://www.cnblogs.com/Carina-baby/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2859233/20220427162558.png" alt="" />...

    uj5u.com 2023-03-27 14:46:35 more
  • 武裝你的WEBAPI-OData聚合查詢

    <a href="https://www.cnblogs.com/podolski/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/616093/20140323000327.png" alt="" /><...

    uj5u.com 2023-03-27 14:46:16 more