最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

ASP.NET Core MVC過濾器運(yùn)行流程解析

 更新時(shí)間:2023年11月26日 16:43:30   作者:東邪獨(dú)孤  
這篇文章主要為大家介紹了ASP.NET Core MVC過濾器運(yùn)行流程解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

MVC 的過濾器

MVC 的過濾器(Filters)也翻譯為“篩選器”。但是老周更喜歡翻譯為“過濾器”,意思上更好理解。

既然都叫過濾器了,就是在MVC的操作方法調(diào)用前后進(jìn)行特殊處理的類型。比如:

a、此調(diào)用是否已授權(quán)?

b、在模型綁定之前要不要修改數(shù)據(jù)源?(可能含有兒童不宜的數(shù)據(jù))

c、在調(diào)用MVC方法前要不要改一改輸入?yún)?shù)?在MVC方法調(diào)用之后要不要處理一下結(jié)果(加點(diǎn)味精,進(jìn)一步調(diào)味)

d、發(fā)生異常后怎么處理?

過濾器可解決上面一堆提問。

在 ASP.NET Core 的 MVC 框架中,所有過濾器都實(shí)現(xiàn)共同接口 IFilterMetadata。該接口空空如也,未定義任何成員。說白了,它的用處是作為一種“記號”。你怎么證明你就是過濾器,嗯,看看你實(shí)現(xiàn)了 IFilterMetadata 接口沒?實(shí)現(xiàn)了就認(rèn)定是過濾器。所以,該接口純粹是個(gè)角色標(biāo)簽。

過濾器專屬命名空間 Microsoft.AspNetCore.Mvc.Filters

咱們寫代碼一般不會實(shí)現(xiàn) IFilterMetadata 接口,畢竟里面什么卵方法都沒有,怎么規(guī)范類型?因此,過濾器專屬命名空間 Microsoft.AspNetCore.Mvc.Filters 下為我們公開了以下接口,方便開發(fā)者實(shí)現(xiàn):

1、IAuthorizationFilter:授權(quán)過濾器,它的優(yōu)先級最高,總是最先運(yùn)行??纯茨阌袥]有權(quán)限調(diào)用 MVC 方法,若沒權(quán)限,就 See you La La。

2、IResourceFilter:資源過濾器。它在授權(quán)過濾成功后、模型綁定前運(yùn)行。可以檢查一下用于綁定的數(shù)據(jù),要不要改一下。

3、IActionFilter:操作方法過濾器,就是針對 MVC Action 的。在操作方法運(yùn)行前后運(yùn)行,可以用來修改輸入?yún)?shù)值。

4、IResultFilter:結(jié)果過濾器。當(dāng) MVC 操作方法運(yùn)行成功后就會運(yùn)行,可以用來修改運(yùn)行結(jié)果。比如加點(diǎn) HTTP 消息頭什么的。

5、IExceptionFilter:當(dāng) MVC 操作方法運(yùn)行過程中發(fā)生異常才會運(yùn)行,無異常就不會運(yùn)行。

…… 其實(shí)還有的,但這里咱們先不提,免得大伙搞得頭暈。

過濾器不止一個(gè),同一類型的過濾還可能有多個(gè),因此,它們就像中間件那樣,一個(gè)個(gè)鏈接起來,形成下水溝,哦不,是調(diào)用管道,或叫調(diào)用棧。于是,這就出現(xiàn)誰先運(yùn)行的問題,雖然上面的介紹有說明,不過那太抽象了。任何編程知識只要能用代碼來驗(yàn)證和觀察,就不用圖表和理論。

過濾器是怎么運(yùn)行

下面,咱們實(shí)現(xiàn)上述幾個(gè)接口,然后往控制臺上打印一些文本,來看看這些過濾器是怎么運(yùn)行的。

public class CustAuthFilter : IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationFilterContext context)
    {
        Console.WriteLine("授權(quán)過濾器運(yùn)行");
    }
}
public class CustResourceFilter : IResourceFilter
{
    public void OnResourceExecuted(ResourceExecutedContext context)
    {
        Console.WriteLine("資源過濾器 - " + $"{nameof(OnResourceExecuted)}方法運(yùn)行");
    }
    public void OnResourceExecuting(ResourceExecutingContext context)
    {
        Console.WriteLine("資源過濾器 - " + $"{nameof(OnResourceExecuting)}方法運(yùn)行");
    }
}
public class CustActionFilter : IActionFilter
{
    public void OnActionExecuted(ActionExecutedContext context)
    {
        Console.WriteLine("操作過濾器 - " + $"{nameof(OnActionExecuted)}方法運(yùn)行");
    }
    public void OnActionExecuting(ActionExecutingContext context)
    {
        Console.WriteLine("操作過濾器 - " + $"{nameof(OnActionExecuting)}方法運(yùn)行");
    }
}
public class CustResultFilter : IResultFilter
{
    public void OnResultExecuted(ResultExecutedContext context)
    {
        Console.WriteLine("結(jié)果過濾器 - " + $"{nameof(OnResultExecuted)}方法運(yùn)行");
    }
    public void OnResultExecuting(ResultExecutingContext context)
    {
        Console.WriteLine("結(jié)果過濾器 - " + $"{nameof(OnResultExecuting)}方法運(yùn)行");
    }
}

這里我沒有實(shí)現(xiàn)異常過濾器,只實(shí)現(xiàn)了授權(quán)、資源、操作方法、結(jié)果這幾個(gè)有代表性的。

授權(quán)過濾器只要實(shí)現(xiàn) OnAuthorization 方法即可。在實(shí)現(xiàn)代碼中,可以通過 HttpContext 對象查找授權(quán)有關(guān)的對象,如果確認(rèn)是沒有訪問權(quán)限的,可以設(shè)置一個(gè)自己定 Result 讓 MVC 操作方法的調(diào)用終止。

資源過濾器要實(shí)現(xiàn)兩個(gè)方法:OnResourceExecuting 方法在模型綁定前調(diào)用,這時(shí)你有機(jī)會修改數(shù)據(jù)源;OnResourceExecuted 方法是在資源過濾之后的其他過濾器運(yùn)行結(jié)束才被調(diào)用,即:

ResourceExecuting
    ........ 剩余過濾器.......
ResourceExecuted

Action 過濾器也要實(shí)現(xiàn)兩個(gè)方法:OnActionExecuting 在操作調(diào)用前運(yùn)行;OnActionExecuted 是在操作方法調(diào)用后運(yùn)行。

結(jié)果過濾器需要實(shí)現(xiàn)兩個(gè)方法:OnResultExecuting 方法在操作結(jié)果執(zhí)行前調(diào)用,這里可以修改 MVC 方法返回的值;OnResultExecuted 方法是在操作結(jié)果執(zhí)行之后調(diào)用,一般這里可以改改HTTP向應(yīng)頭、Cookie 什么的。

其實(shí)咱們剛實(shí)現(xiàn)的過濾器都是同步版本,這些過濾器都有配套的異步版本,接口都是以 IAsync 開頭。這里咱們先不用管同步異步,避免搞得復(fù)雜了。也不要去理會過濾器是全局的還是局部的,下面咱們統(tǒng)一把它們注冊為全局的。配置方法是通過 MVC 選項(xiàng)類的 Filters 集合,把要用的過濾器添加進(jìn)去即可。

var builder = WebApplication.CreateBuilder(args);
 builder.Services.AddControllersWithViews(options =>
 {
     // 配置全局過濾器
     options.Filters.Add<CustAuthFilter>();
     options.Filters.Add<CustResourceFilter>();
     options.Filters.Add<CustActionFilter>();
     options.Filters.Add<CustResultFilter>();
 });
 var app = builder.Build();

添加一個(gè)“狗頭”控制器,用于測試。

public class GouTouController : Controller
{
    public IActionResult Index()
    {
        Console.WriteLine("Index操作運(yùn)行");
        return View();
    }
}

為了防止 ASP.NET Core 應(yīng)用程序輸出的日志干擾咱們查看控制臺內(nèi)容,咱們禁用所有日志輸出。打開 appsettings.json 文件,把所有日志類別的記錄級別改為 None。

{
  "Logging": {
    "LogLevel": {
      "*": "None"
    }
  },
  "AllowedHosts": "*"
}

星號 * 的意思就是代表所有類別的日志,LogLevel 為 None 就不會輸出日志了(貌似有個(gè)別日志禁用不了)。

運(yùn)行程序后,控制臺打印出這樣的內(nèi)容:

 這個(gè)流程現(xiàn)在是不是很清晰了?咱們畫圖表了,直接這樣表達(dá)就好:

Author
Resource Executing
    Action Executing
            Action Running
    Action Executed
    Result Executing
            Result Running
    Result Executed
Resource Executed

局部過濾器的運(yùn)行過程與全局過濾器相同,如果局部和全局過濾器同時(shí)使用,那會發(fā)生什么呢?咱們試試。

局部和全局過濾器使用

接下來我們?yōu)槭跈?quán)過濾、資源過濾、操作過濾、結(jié)果過濾各創(chuàng)建兩個(gè)類——用于局部和全局。實(shí)際開發(fā)中一般不需要這樣搞,通常全局和局部寫一個(gè)類就行,畢竟過濾器類型在全局和局部是通用的。我這里只為了演示。局部過濾器是通過特性類的方式應(yīng)用到 MVC 方法上的,所以,局部過濾器除了實(shí)現(xiàn)過濾器接口,還要從 Attribute 類派生。

1、實(shí)現(xiàn)局部、全局授權(quán)過濾器。

// 授權(quán)過濾器-局部
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class MyAuthorFilterAttribute : Attribute, IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationFilterContext context)
    {
        Console.WriteLine("局部:授權(quán)過濾器運(yùn)行");
    }
}

// 授權(quán)過濾器-全局
public class GlobAuthorFilter : IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationFilterContext context)
    {
        Console.WriteLine("全局:授權(quán)過濾器運(yùn)行");
    }
}

2、實(shí)現(xiàn)局部、全局資源過濾器。

// 資源過濾器-局部
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class MyResourceFilterAttribute : Attribute, IResourceFilter
{
    public void OnResourceExecuted(ResourceExecutedContext context)
    {
        Console.WriteLine("局部:資源過濾器-Executed");
    }

    public void OnResourceExecuting(ResourceExecutingContext context)
    {
        Console.WriteLine("局部:資源過濾器-Executing");
    }
}

// 資源過濾器-全局
public class GlobResourceFilter : IResourceFilter
{
    public void OnResourceExecuted(ResourceExecutedContext context)
    {
        Console.WriteLine("全局:資源過濾器-Executed");
    }

    public void OnResourceExecuting(ResourceExecutingContext context)
    {
        Console.WriteLine("全局:資源過濾器-Executing");
    }
}

3、實(shí)現(xiàn)局部、全局操作過濾器。

// 操作過濾器-局部
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class MyActionFilterAttribute : Attribute, IActionFilter
{
    public void OnActionExecuted(ActionExecutedContext context)
    {
        Console.WriteLine("局部:操作過濾器-Executed");
    }

    public void OnActionExecuting(ActionExecutingContext context)
    {
        Console.WriteLine("局部:操作過濾器-Executing");
    }
}

// 操作過濾器-全局
public class GlobActionFilter : IActionFilter
{
    public void OnActionExecuted(ActionExecutedContext context)
    {
        Console.WriteLine("全局:操作過濾器-Executed");
    }

    public void OnActionExecuting(ActionExecutingContext context)
    {
        Console.WriteLine("全局:操作過濾器-Executing");
    }
}

4、實(shí)現(xiàn)局部、全局結(jié)果過濾器。

// 結(jié)果過濾器-局部
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class MyResultFilterAttribute : Attribute, IResultFilter
{
    public void OnResultExecuted(ResultExecutedContext context)
    {
        Console.WriteLine("局部:結(jié)果過濾器-Executed");
    }
    public void OnResultExecuting(ResultExecutingContext context)
    {
        Console.WriteLine("局部:結(jié)果過濾器-Executing");
    }
}
// 結(jié)果過濾器-全局
public class GlobResultFilter : IResultFilter
{
    public void OnResultExecuted(ResultExecutedContext context)
    {
        Console.WriteLine("全局:結(jié)果過濾器-Executed");
    }
    public void OnResultExecuting(ResultExecutingContext context)
    {
        Console.WriteLine("全局:結(jié)果過濾器-Executing");
    }
}

先注冊全局過濾器。

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers(options =>
{
    // 添加全局過濾器
    options.Filters.Add<GlobActionFilter>();
    options.Filters.Add<GlobAuthorFilter>();
    options.Filters.Add<GlobResourceFilter>();
    options.Filters.Add<GlobResultFilter>();
});
var app = builder.Build();

局部過濾器以特性方式應(yīng)用于 MVC 操作方法。

public class SpiderController : ControllerBase
{
    [MyResourceFilter]
    [MyResultFilter]
    [MyActionFilter, MyAuthorFilter]
    public IActionResult Index()
    {
        Console.WriteLine("Index操作被調(diào)用");
        return Content("大火燒了毛毛蟲");
    }
}

和上一個(gè)例子一樣,禁用日志輸出(appsettings.json文件)。

{
  "Logging": {
    "LogLevel": {
      "*": "None"
    }
  },
  ……
}

程序運(yùn)行后,控制臺打印以下內(nèi)容:

 過濾器按 授權(quán)->資源->操作->結(jié)果 運(yùn)行的次序不變。在同種過濾器中,全局過濾器優(yōu)先運(yùn)行。

全局授權(quán)過濾器
局部授權(quán)過濾器
全局資源過濾器 - 前
    局部資源過濾器 - 前
        全局操作過濾器 - 前
            局部操作過濾器 - 前
                【調(diào)用 MVC 操作方法】
            局部操作過濾器 - 后
        全局操作過濾器 - 后
        全局結(jié)果過濾器 - 前
             局部結(jié)果過濾器 - 前
                【執(zhí)行操作結(jié)果】
             局部結(jié)果過濾器 - 后
        全局結(jié)果過濾器 - 后
    局部資源過濾器 - 后
全局資源過濾器 - 后

另外,有一件事要注意:如果你的控制器的基類是 Controller,那么,還有優(yōu)先更高的 Action Filter。看看 Controller 類它實(shí)現(xiàn)了啥接口。

public abstract class Controller : ControllerBase, IActionFilter, IFilterMetadata, IAsyncActionFilter, IDisposable

咱們把剛才的控制器代碼改一下,讓它繼承 Controller 類,并重寫 OnActionExecuting、OnActionExecuted 方法。

public class SpiderController : Controller
{
    ……
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        Console.WriteLine("控制器實(shí)現(xiàn)的操作過濾器-Executing");
        base.OnActionExecuting(context);
    }
    public override void OnActionExecuted(ActionExecutedContext context)
    {
        Console.WriteLine("控制器實(shí)現(xiàn)的操作過濾器-Executed");
        base.OnActionExecuted(context);
    }
}

然后再次運(yùn)行程序,控制臺將打印以下內(nèi)容:

看,這個(gè)由控制器類實(shí)現(xiàn)的 Action 過濾器比全局的還早運(yùn)行。

以上就是ASP.NET Core MVC過濾器運(yùn)行流程解析的詳細(xì)內(nèi)容,更多關(guān)于ASP.NET Core MVC過濾器的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • ASP.NET緩存 方法和最佳實(shí)踐

    ASP.NET緩存 方法和最佳實(shí)踐

    在 ASP.NET 提供的許多特性中,緩存支持無疑是我最欣賞的特性,我這樣說當(dāng)然是有充分理由的。
    2010-06-06
  • ASP.NET MVC 數(shù)據(jù)驗(yàn)證及相關(guān)內(nèi)容

    ASP.NET MVC 數(shù)據(jù)驗(yàn)證及相關(guān)內(nèi)容

    這篇文章主要介紹了ASP.NET MVC 數(shù)據(jù)驗(yàn)證及相關(guān)內(nèi)容的相關(guān)資料,需要的朋友可以參考下
    2014-10-10
  • 3分鐘快速學(xué)會在ASP.NET Core MVC中如何使用Cookie

    3分鐘快速學(xué)會在ASP.NET Core MVC中如何使用Cookie

    這篇文章主要給大家介紹了關(guān)于如何通過3分鐘快速學(xué)會在ASP.NET Core MVC中使用Cookie的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用ASP.NET具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • asp.net(c#)文件下載實(shí)現(xiàn)代碼

    asp.net(c#)文件下載實(shí)現(xiàn)代碼

    本文通過一個(gè)實(shí)例向大家介紹用C#進(jìn)行Internet通訊編程的一些基本知識。我們知道.Net類包含了請求/響應(yīng)層、應(yīng)用協(xié)議層、傳輸層等層次。
    2009-11-11
  • VS2022?.NET5一鍵發(fā)布到遠(yuǎn)程騰訊云IIS服務(wù)器的詳細(xì)步驟

    VS2022?.NET5一鍵發(fā)布到遠(yuǎn)程騰訊云IIS服務(wù)器的詳細(xì)步驟

    這篇文章主要介紹了VS2022?.NET5一鍵發(fā)布到遠(yuǎn)程騰訊云IIS服務(wù)器,首先需要添加服務(wù)器相關(guān)功能,文中通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-04-04
  • ASP.NET?MVC5網(wǎng)站開發(fā)之總體概述(一)

    ASP.NET?MVC5網(wǎng)站開發(fā)之總體概述(一)

    這篇文章主要為大家詳細(xì)介紹了ASP.NET?MVC5網(wǎng)站開發(fā)之總體概述,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-08-08
  • asp.net MVC實(shí)現(xiàn)簡單的上傳功能

    asp.net MVC實(shí)現(xiàn)簡單的上傳功能

    MVC中上傳變得越來越容易,可是對于新手這個(gè)也還是不知道如何實(shí)現(xiàn),以下方式實(shí)現(xiàn)MVC的上傳功能,以下2種方法都是可以實(shí)現(xiàn)的,其中的代碼參考了藍(lán)色小鋪和重典的文章。
    2009-11-11
  • 利用ASP.NET MVC和Bootstrap快速搭建個(gè)人博客之后臺dataTable數(shù)據(jù)列表

    利用ASP.NET MVC和Bootstrap快速搭建個(gè)人博客之后臺dataTable數(shù)據(jù)列表

    jQuery dataTables 插件是一個(gè)優(yōu)秀的表格插件,應(yīng)用非常廣泛,本文給大家介紹利用ASP.NET MVC和Bootstrap快速搭建個(gè)人博客之后臺dataTable數(shù)據(jù)列表,非常不錯(cuò),具有參考借鑒價(jià)值,感興趣的朋友一起看下吧
    2016-07-07
  • .NET 6開發(fā)TodoList應(yīng)用之使用AutoMapper實(shí)現(xiàn)GET請求

    .NET 6開發(fā)TodoList應(yīng)用之使用AutoMapper實(shí)現(xiàn)GET請求

    我們希望接受的請求和返回的值具有以下兩點(diǎn)需要遵循的原則:每個(gè)model被且只被一個(gè)API消費(fèi);每個(gè)model里僅僅包含API發(fā)起方希望包含的必要字段或?qū)傩浴utoMapper庫就是為了實(shí)現(xiàn)這個(gè)需求而存在的。本文將為大家介紹AutoMapper如何實(shí)現(xiàn)GET請求,需要的可以參考一下
    2021-12-12
  • Ajax.net 顯示錯(cuò)誤信息的設(shè)置

    Ajax.net 顯示錯(cuò)誤信息的設(shè)置

    有時(shí)候我們在使用asp.net想讓他顯示出錯(cuò)的原因等情況,大家可以仔細(xì)看下參數(shù),屬性等
    2009-01-01

最新評論

黄石市| 上林县| 伊通| 乌什县| 青海省| 绵阳市| 永寿县| 麻阳| 龙里县| 屯门区| 澜沧| 信阳市| 松桃| 大姚县| 梅州市| 虞城县| 娄烦县| 六枝特区| 大荔县| 吉木萨尔县| 聊城市| 南皮县| 卫辉市| 泾川县| 金寨县| 黑水县| 荔波县| 边坝县| 芮城县| 密云县| 全椒县| 东安县| 龙州县| 辰溪县| 开封市| 绥滨县| 江西省| 福清市| 汤原县| 兴化市| 崇礼县|