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

聊聊 ASP.NET Core 中間件和過濾器的區(qū)別解析

 更新時(shí)間:2026年04月06日 07:56:43   作者:dotNET 實(shí)驗(yàn)室  
本文介紹了ASP.NETCore中的中間件和過濾器的區(qū)別,總結(jié)了常用內(nèi)置中間件和過濾器,幫助開發(fā)者更好地理解和使用它們,感興趣的朋友跟隨小編一起看看吧

引言

不知道你有沒有在面試中遇到過這樣的問題:"中間件和過濾器的區(qū)別是什么?",或者在平時(shí)開發(fā)中思考過:"一個(gè)請(qǐng)求進(jìn)來,ASP.NET Core 到底是怎么一步步處理它的?"

這篇文章就來聊聊,不會(huì)涉及太深的源碼,主要面向初級(jí)開發(fā)者,幫你建立一個(gè)清晰的認(rèn)知。

先說中間件

中間件是 ASP.NET Core 處理 HTTP 請(qǐng)求的基本部件,是框架本身的組成部分。

每一個(gè)請(qǐng)求進(jìn)來后,按照 Use 的注冊(cè)順序,依次經(jīng)過每一個(gè)中間件,到達(dá)終端后,再按照相反的方向依次返回。一系列中間件串聯(lián)起來,就組成了 ASP.NET Core 的請(qǐng)求管道。這個(gè)模型有人叫"洋蔥模型",也有人叫"俄羅斯套娃模型",都是一個(gè)意思。

請(qǐng)求 →  中間件A → 中間件B → 中間件C(終端)
響應(yīng) ←  中間件A ← 中間件B ←

中間件可以做什么呢?它收到請(qǐng)求后,可以在請(qǐng)求/響應(yīng)對(duì)象上加點(diǎn)佐料(自己的邏輯),然后調(diào)用 next() 把請(qǐng)求傳遞給下一個(gè)中間件。如果不調(diào)用 next(),請(qǐng)求就在這里短路了,后面的中間件不會(huì)執(zhí)行,這個(gè)中間件就成了終端中間件。

下面是一個(gè)簡單示例,演示如何自定義一個(gè)記錄請(qǐng)求耗時(shí)的中間件:

// 定義中間件類
public class TimingMiddleware
{
    private readonly RequestDelegate _next;

    public TimingMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        var sw = Stopwatch.StartNew();

        // 調(diào)用 next(),請(qǐng)求繼續(xù)往下走
        await _next(context);

        // next() 返回后,響應(yīng)正在往回走
        sw.Stop();
        Console.WriteLine($"[{context.Request.Path}] 耗時(shí):{sw.ElapsedMilliseconds}ms");
    }
}

// 在 Program.cs 中注冊(cè)
var app = builder.Build();

app.UseMiddleware<TimingMiddleware>();  // 注冊(cè)自定義中間件

app.UseRouting();
app.UseAuthorization();
app.MapControllers();

app.Run();

如果你不想單獨(dú)定義一個(gè)類,也可以用 app.Use 直接寫一個(gè)內(nèi)聯(lián)中間件:

app.Use(async (context, next) =>
{
    Console.WriteLine($"請(qǐng)求進(jìn)來了:{context.Request.Path}");

    await next();  // 傳遞給下一個(gè)中間件

    Console.WriteLine($"響應(yīng)回來了:{context.Response.StatusCode}");
});

這里注冊(cè)的是終端中間件,不接受 next,請(qǐng)求到這里就結(jié)束了,不會(huì)再往下傳:

app.Run(async context =>
{
    await context.Response.WriteAsync("到終點(diǎn)了,不繼續(xù)往下走");
});

再聊過濾器

過濾器是在路由中間件內(nèi)部起作用的。

請(qǐng)求經(jīng)過中間件管道,到達(dá)路由中間件后,路由中間件確定了要調(diào)用哪個(gè) Controller / Action。在真正執(zhí)行 Action 的前后,過濾器就夾在這里介入。

用一張簡單的示意圖來表示:

請(qǐng)求進(jìn)來
  → 中間件們
    → 路由中間件(確定目標(biāo) Action)
      → 過濾器們(Action 執(zhí)行前后插手)
        → Action 執(zhí)行
      ← 過濾器們
    ← 路由中間件
  ← 中間件們
響應(yīng)返回

正因?yàn)檫^濾器處于路由之后,所以它能拿到 MVC 的上下文信息,比如當(dāng)前是哪個(gè) Action、Action 上有哪些 Attribute、ModelState 是否合法等等。這是普通中間件做不到的,因?yàn)橹虚g件執(zhí)行的時(shí)候,路由還沒解析呢。

// 定義過濾器類,繼承 ActionFilterAttribute
public class ValidateModelAttribute : ActionFilterAttribute
{
    // 在 Action 執(zhí)行之前觸發(fā)
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (!context.ModelState.IsValid)
        {
            // ModelState 校驗(yàn)不通過,直接短路,返回 400
            var errors = context.ModelState
                .Where(e => e.Value?.Errors.Count > 0)
                .ToDictionary(
                    e => e.Key,
                    e => e.Value!.Errors.Select(x => x.ErrorMessage).ToArray()
                );

            context.Result = new BadRequestObjectResult(new
            {
                code = 400,
                message = "參數(shù)校驗(yàn)失敗",
                errors
            });
        }
    }

    // 在 Action 執(zhí)行之后觸發(fā)
    public override void OnActionExecuted(ActionExecutedContext context)
    {
        // 可以在這里統(tǒng)一處理響應(yīng),比如包一層統(tǒng)一的返回格式
    }
}

使用方式很簡單,直接作為 Attribute 標(biāo)注在 Controller 或 Action 上:

// 標(biāo)注在單個(gè) Action 上
[HttpPost]
[ValidateModel]
public IActionResult CreateUser([FromBody] CreateUserRequest request)
{
    // 走到這里說明 ModelState 已經(jīng)通過校驗(yàn)
    return Ok(new { message = "創(chuàng)建成功" });
}

// 也可以標(biāo)注在 Controller 上,對(duì)所有 Action 生效
[ApiController]
[ValidateModel]
public class UserController : ControllerBase
{
    // ...
}

如果想全局生效,在 Program.cs 里注冊(cè)就行:

builder.Services.AddControllers(options =>
{
    options.Filters.Add<ValidateModelAttribute>();  // 全局注冊(cè)
});

它倆的區(qū)別

中間件過濾器
作用范圍所有 HTTP 請(qǐng)求,包括靜態(tài)文件僅限 Controller / Action
典型使用場(chǎng)景限流、壓縮、跨域、日志、認(rèn)證權(quán)限校驗(yàn)、參數(shù)校驗(yàn)、統(tǒng)一響應(yīng)封裝、異常處理

一句話總結(jié):中間件是 HTTP 管道的基礎(chǔ)設(shè)施,過濾器是 MVC 系的切面機(jī)制,它們不是同一層次的東西。

給你一個(gè)小技巧,不確定用哪個(gè)的時(shí)候,問自己一個(gè)問題:我需要知道當(dāng)前是哪個(gè) Action 嗎? 需要的話用過濾器,不需要的話中間件就夠了。

內(nèi)置清單

最后整理一份 ASP.NET Core 已經(jīng)提供的常用中間件和過濾器,遇到需求的時(shí)候先查查有沒有現(xiàn)成的,別重復(fù)造輪子。

常用內(nèi)置中間件:

中間件說明
UseRouting路由解析
UseAuthentication認(rèn)證
UseAuthorization授權(quán)
UseStaticFiles靜態(tài)文件服務(wù)
UseCors跨域
UseExceptionHandler全局異常處理
UseHttpsRedirectionHTTPS 重定向
UseResponseCompression響應(yīng)壓縮
UseRateLimiter限流(.NET 7 新增)

內(nèi)置過濾器:

過濾器說明
[Authorize]授權(quán)校驗(yàn)
[AllowAnonymous]允許匿名訪問
[RequireHttps]強(qiáng)制 HTTPS
[ValidateAntiForgeryToken]防止 CSRF 攻擊
[ResponseCache]響應(yīng)緩存
[Produces]指定響應(yīng)內(nèi)容類型
[Consumes]指定請(qǐng)求內(nèi)容類型

到此這篇關(guān)于聊聊 ASP.NET Core 中間件和過濾器的區(qū)別解析的文章就介紹到這了,更多相關(guān)asp.net core中間件和過濾器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

贡嘎县| 溧水县| 手游| 桃园县| 梅州市| 旌德县| 云霄县| 达日县| 吉木乃县| 广南县| 时尚| 连州市| 韩城市| 阿尔山市| 滕州市| 根河市| 瑞昌市| 平果县| 革吉县| 敦煌市| 塔城市| 新安县| 长沙市| 正安县| 定远县| 安徽省| 利津县| 板桥市| 鄯善县| 比如县| 海原县| 儋州市| 嘉祥县| 高阳县| 东港市| 潞城市| 通道| 竹山县| 泉州市| 大洼县| 临泽县|