asp.net core系列 68 Filter管道過濾器

来源:https://www.cnblogs.com/MrHSR/archive/2019/07/16/11184801.html
-Advertisement-
Play Games

一.概述 本篇詳細瞭解一下asp.net core filters,filter叫"篩選器"也叫"過濾器",是請求處理管道中的特定階段之前或之後運行代碼。filter用於處理橫切關註點。 橫切關註點的示例包括:錯誤處理、緩存、配置、授權和日誌記錄。 filter可以避免重覆代碼,通過Attribut ...


一.概述

  本篇詳細瞭解一下asp.net core filters,filter叫"篩選器"也叫"過濾器",是請求處理管道中的特定階段之前或之後運行代碼。filter用於處理橫切關註點。 橫切關註點的示例包括:錯誤處理、緩存、配置、授權和日誌記錄。 filter可以避免重覆代碼,通過Attribute特性來實現filter過濾。Filter適應於 Razor Pages,  API controllers,  mvc controllers。filter基類是IFilterMetadata 介面,該介面只是用來標記是一個filter過濾器。

  前段時間在項目中實現了IAsyncAuthorizationFilter介面對用戶訪問controller或action進行了授權,在OnAuthorizationAsync方法中使用context.Result可使管道短道。IAsyncAuthorizationFilter是屬於授權過濾器中的一種。勿在授權過濾器內拋出異常,這是因為所拋出的異常不會被處理。下麵是簡要的實現授權代碼:

   [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    public class PermissionFilter : Attribute,IAsyncAuthorizationFilter
  {
    public   Task OnAuthorizationAsync(AuthorizationFilterContext context)
        {
                IIdentity user = context.HttpContext.User.Identity;
                if (!user.IsAuthenticated)
                {
            //跳轉到登錄頁
              context.Result = new LocalRedirectResult(url);
             return Task.CompletedTask;
             }
 
         //根據當前用戶,判斷當前訪問的action,沒有許可權時返回403錯誤
         context.Result = new ForbidResult();
            
             return Task.CompletedTask;
     }
    }

  在官方文檔中說到:"自定義授權篩選器Filter需要自定義授權框架, 建議配置授權策略或編寫自定義授權策略,而不是編寫自定義Filter篩選器"。

  這裡的意思是說,如果在項目中不使用asp.net core自帶的identity,那麼需要自定義授權框架,也就是需要自己建立一套用戶許可權表。 如果使用了identity建議配置授權策略或編寫自定義授權策略。如果不用identity自己建立用戶許可權表,那麼就可以編寫自定義Filter篩選器。我在項目開發中是自己建立了用戶許可權表沒有用identity。因為使用identity表還需要擴展欄位,而且與EF core結合緊密,如果不使用EF core需要重寫訪問identity表的實現。

  下麵是identity與ef core相關的代碼: 

   services.AddIdentity<ApplicationUser, IdentityRole>()
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultTokenProviders();

   -- TContext必須是DbContext類型
    public static IdentityBuilder AddEntityFrameworkStores<TContext>(this IdentityBuilder builder) where TContext : DbContext

 

二.Filter 篩選器類型

    Authorization filters  授權篩選器

    Resource filters       資源篩選器

    Action filters            操作篩選器 (Razor Pages 中使用 IPageFilter 和 IAsyncPageFilter)

    Exception filters      異常篩選器

    Result filters            結果篩選器

    每種Filter 類型都在Filter 管道中的不同階段執行,當用戶請求進來時,經過Filter管道,執行Filter的階段順序如下所示:

    上面每種Filter 類型都有自己的介面,都同時支持同步和非同步實現,上面的授權示例就是一個非同步實現授權篩選器IAsyncAuthorizationFilter。Filter 介面或直接或間接實現了IFilterMetadata介面,IFilterMetadata介面只是用來標記是一個Filter 。

 

三.filter篩選器作用域

  (1) 將 attribute特性應用在 action上。

  (2) 將 attribute特性應用在 controller上。

  (3) 全局篩選器應用在controller和action上

    下麵使用全局篩選器,使用MvcOptions.Filters 集合,添加三個篩選器,如下麵的代碼所示:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(options =>
    {
        options.Filters.Add(new AddHeaderAttribute("GlobalAddHeader",
            "Result filter added to MvcOptions.Filters"));         // An instance
        options.Filters.Add(typeof(MySampleActionFilter));         // By type
        options.Filters.Add(new SampleGlobalActionFilter());       // An instance
    }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
//實現了內置篩選器屬性
public class AddHeaderAttribute : ResultFilterAttribute
//實現了操作篩選器
public class MySampleActionFilter : IActionFilter
//實現了操作篩選器
public class SampleGlobalActionFilter : IActionFilter

 

四.內置篩選器Attribute屬性

    下麵都是filter內置的屬性類,需要去實現這些抽象屬性類。

      ActionFilterAttribute
      ExceptionFilterAttribute
      ResultFilterAttribute
      FormatFilterAttribute
      ServiceFilterAttribute
      TypeFilterAttribute

  下麵一個示例是為響應添加標頭,開發人員來實現ResultFilterAttribute抽象類:

public class AddHeaderAttribute : ResultFilterAttribute
{
    private readonly string _name;
    private readonly string _value;

    public AddHeaderAttribute(string name, string value)
    {
        _name = name;
        _value = value;
    }

    public override void OnResultExecuting(ResultExecutingContext context)
    {
        context.HttpContext.Response.Headers.Add( _name, new string[] { _value });
        base.OnResultExecuting(context);
    }
}

     通過使用屬性,篩選器可接收參數,將 AddHeaderAttribute 添加到控制器或操作方法,並指定 HTTP 標頭的名稱和值,如下所示:

        [AddHeader("Author", "Steve Smith @ardalis")]
        public IActionResult Hello(string name)
        {
            return Content($"Hello {name}");
        }
    

 

五.Filter三種依賴關係註入

    (1)ServiceFilterAttribute
    (2)TypeFilterAttribute
    (3)在屬性上實現 IFilterFactory。

  5.1 ServiceFilterAttribute演示

    下麵是在 ConfigureServices 中註冊服務篩選器實現類型,內置的ServiceFilterAttribute會從DI 檢索篩選器實例。

public class AddHeaderResultServiceFilter : IResultFilter
{
    private ILogger _logger;
    public AddHeaderResultServiceFilter(ILoggerFactory loggerFactory)
    {
        _logger = loggerFactory.CreateLogger<AddHeaderResultServiceFilter>();
    }

    public void OnResultExecuting(ResultExecutingContext context)
    {
        var headerName = "OnResultExecuting";
        context.HttpContext.Response.Headers.Add(
            headerName, new string[] { "ResultExecutingSuccessfully" });
        _logger.LogInformation($"Header added: {headerName}");
    }

    public void OnResultExecuted(ResultExecutedContext context)
    {
        // Can't add to headers here because response has started.
    }
}

     在以下代碼中,AddHeaderResultServiceFilter 將添加到 DI 容器中:

    services.AddScoped<AddHeaderResultServiceFilter>();

    在以下代碼中,通過ServiceFilter 屬性,將從 DI 中檢索 AddHeaderResultServiceFilter 篩選器的實例:

[ServiceFilter(typeof(AddHeaderResultServiceFilter))]
public IActionResult Index()
{
    return View();
}

 

六. 各種篩選器介紹

  6.1 Authorization filters 

    是篩選器管道中第一個運行的篩選器。是控制對Action方法的訪問。

     在Action之前執行的方法,沒有在Action之後執行的方法。

       註意:不要在授權篩選器中引發異常

    場景:

      如果使用identity,可用配置授權策略或編寫自定義授權策略。詳情查看identity部分。

      如果不使用identity,可編寫自定義篩選器。

 

  6.2 Resource filters

    實現 IResourceFilter 或 IAsyncResourceFilter 介面。

    它執行會覆蓋篩選器管道的絕大部分。

    它在授權篩選器之後運行。

    場景:

      可以防止模型綁定訪問表單數據。

      用於上傳大型文件,以防止表單數據被讀入記憶體。

 

  6.3 Action filters

    實現 IActionFilter 或 IAsyncActionFilter 介面。

    它圍繞著Action方法的執行。

    它方法中有個重要屬性ActionArguments ,用於讀取action的輸入參數。

    場景:

      可以在該介面的OnActionExecuting方法中進行驗證模型狀態(ModelState.IsValid),如果狀態無效,則返回錯誤(這個場景很有用)。

 

  6.4 Exception filters

    實現 IExceptionFilter 或 IAsyncExceptionFilter。

    它沒有之前和之後的事件,

    可實現該介面的 OnException 或 OnExceptionAsync方法。

    處理 Razor 頁面或控制器創建、模型綁定、操作篩選器或操作方法中發生的未經處理的異常

    若要處理異常(不再throw),請將 ExceptionHandled 屬性設置為 true。

    場景:

      實現常見的錯誤處理策略。

      非常適合捕獲發生在action中的異常。

 

  6.5 Result filters

    實現 IResultFilter 或 IAsyncResultFilter 或 IAlwaysRunResultFilter 或 IAsyncAlwaysRunResultFilter

    它執行圍繞著action結果的執行。當異常篩選器處理異常時,不執行結果篩選器

    如果在 IResultFilter.OnResultExecuting 中引發異常,則會導致:

      (1) 阻止action結果和後續篩選器的執行。

      (2) 結果被視為失敗。

 

 

  更詳細的資料參考官網文檔,後續在實際項目中應用到的篩選器,將會再本篇繼續補上。

  參考資料:

    官方文檔

    官方示例代碼


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 大二的一個項目需要用到Activex技術將讀取到串口中的數據在後臺獲取到,並將串口的數據寫入資料庫,這個過程需要在後臺使用C#調用Activex控制項已經使用的方法,然後在前端通過JavaScript進行調用串口的數據進行賦值 <script type="text/javascript"> funct ...
  • 獲取網路文件,通過流保存文件。 //網路路徑文件 string pathUrl = "http://localhost:805/js/site.zip"; System.Net.HttpWebRequest request = null; System.Net.HttpWebResponse res ...
  • 項目中有些時候需要用到正則表達式,但是自己對正則表達式不熟悉,每次學習完,過一段時間(長時間)不用,就又忘了,每次需要用到的時候都需要百度下,比較麻煩,這裡把C#中經常用到的正則表達式做下總結。 正則表達式常用的環境 爬蟲、網站數據驗證、日誌分析、字元串替換、獲取子字元串、文本處理、字元串處理等 正 ...
  • 學習筆記,第一次記錄避免忘記 首先介紹一下本地環境是windows2008 R2-64位。 1. 到nginx官網上下載最新穩定版的安裝包,http://nginx.org/en/download.html; 2.下載後解壓到對應文件夾 3.使用cmd命令進入文件目錄,輸入nginx.exe或者st ...
  • 在這一篇文章中我們創建一個菜單,並通過這個菜單調用我們之前寫的增刪除改查的功能。 ...
  • SQLite簡易版ORM 首先打開項目,使用nuget搜索sqlite-net,如下圖: 下載完成後,我們會多出兩個文件,SQLite.cs和SQLiteAsync.cs。 我們新建一個文件夾SQLiteResources,把這倆文件放進去。 然後我們創建兩個表實體,如下: 接下來我們創建一個SQL ...
  • 小白開學Asp.Net Core 《八》 — — .Net Core 數據保護組件 1、背景 我在搞(https://github.com/AjuPrince/Aju.Carefree)這個開源項目的時候,想做一些防止惡意攻擊的小功能(如果 我通過頁面 /Dome/GetData?id=123,那是 ...
  • 最近剛好在學習NetCore框架所以就在網上搜索了一下相關的開源框架項目,正好在Github上找到了一個不錯的開源框架所以推薦給大家看看哈哈哈。 1:項目相關技術 運行NetCore SDK版本為2.2+ 資料庫:Mysql 5.7+ 使用SqlSugar ORM 2:項目源代碼地址: github ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...