在 .NET Core 中,中间件(Middleware) 是处理 HTTP 请求和响应的核心组件。它们被组织成一个请求处理管道,每个中间件都可以在请求到达最终处理程序之前或之后执行操作。中间件可以用于实现各种功能,如身份验证、路由、日志记录、异常处理、静态文件服务等。


什么是中间件?

中间件是 HTTP 请求管道中的一个处理单元,负责处理传入的 HTTP 请求和返回的 HTTP 响应。每个中间件都有以下职责:

  1. 处理请求:可以对请求进行预处理(如修改请求内容、验证身份等)。
  2. 决定是否继续传递请求:可以选择将请求传递给下一个中间件,或者直接返回响应(短路请求管道)。
  3. 处理响应:可以在响应返回给客户端之前进行后处理(如添加响应头、记录日志等)。

中间件的工作原理

中间件的工作原理可以概括为以下几个步骤:

  1. 请求进入管道
    • 当一个 HTTP 请求进入应用程序时,它首先通过一系列的中间件组件。
    • 每个中间件都有机会处理请求,并决定是否将请求传递给下一个中间件。
  2. 中间件的执行顺序
    • 中间件是按照添加的顺序依次执行的。
    • 例如,身份验证中间件通常应该在路由中间件之前执行,以确保在路由处理请求之前已经进行了身份验证。
  3. 中间件的组成
    • 每个中间件通常是一个 Func<requestdelegate, requestdelegate=""></requestdelegate,> 委托,或者是一个实现了 IMiddleware 接口的类。
    • RequestDelegate 是一个表示处理 HTTP 请求的委托,它接收一个 HttpContext 对象并返回一个 Task
  4. 中间件的执行流程
    • 当请求进入中间件时,中间件可以选择:
      • 处理请求并直接返回响应(短路请求管道)。
      • 将请求传递给下一个中间件(调用 next(context))。
    • 如果中间件调用了 next(context),那么请求将继续传递到下一个中间件。
    • 当请求通过所有中间件后,最终的处理程序(如控制器)将处理请求并生成响应。
    • 响应会按照相反的顺序通过中间件管道返回给客户端。

常见的中间件及其工作原理

以下是一些常见的中间件及其工作原理:

1. 身份验证中间件(Authentication Middleware)

  • 作用:用于处理用户身份验证。
  • 工作原理
    • 在请求到达控制器之前,身份验证中间件会检查请求中是否包含有效的身份验证信息(如 JWT 令牌、Cookie 等)。
    • 如果身份验证成功,中间件会将用户信息存储在 HttpContext.User 中。
    • 如果身份验证失败,中间件可以重定向到登录页面或返回 401 未授权响应。

示例

public void Configure(IApplicationBuilder app)
{
    app.UseAuthentication(); // 启用身份验证
    app.UseAuthorization();  // 启用授权
}

2. 路由中间件(Routing Middleware)

  • 作用:用于将请求路由到相应的处理程序(如控制器)。
  • 工作原理
    • 路由中间件会解析请求的 URL 和 HTTP 方法,并根据配置的路由规则将请求映射到相应的处理程序。
    • 路由规则可以通过 UseRouting 和 UseEndpoints 配置。

示例

public void Configure(IApplicationBuilder app)
{
    app.UseRouting(); // 启用路由解析
    app.UseEndpoints(endpoints =>
                     {
                         endpoints.MapControllerRoute(
                             name: "default",
                             pattern: "{controller=Home}/{action=Index}/{id?}");
                     });
}

3. 静态文件中间件(Static Files Middleware)

  • 作用:用于提供静态文件(如 HTML、CSS、JavaScript 文件)。
  • 工作原理
    • 静态文件中间件会检查请求的 URL,如果请求的是静态文件(如 wwwroot 目录下的文件),则直接返回文件内容。
    • 如果请求的不是静态文件,则将请求传递给下一个中间件。

示例

public void Configure(IApplicationBuilder app)
{
    app.UseStaticFiles(); // 启用静态文件服务
}

4. 异常处理中间件(Exception Handling Middleware)

  • 作用:用于捕获和处理应用程序中的异常。
  • 工作原理
    • 异常处理中间件会捕获管道中抛出的异常,并根据配置返回友好的错误页面或 JSON 响应。
    • 通常用于开发环境和生产环境。

示例

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage(); // 开发环境:显示详细错误页面
    }
    else
    {
        app.UseExceptionHandler("/Home/Error"); // 生产环境:重定向到错误页面
    }
}

5. 日志记录中间件(Logging Middleware)

  • 作用:用于记录请求和响应的日志信息。
  • 工作原理
    • 日志记录中间件可以在请求进入和离开管道时记录日志。
    • 通常通过第三方库(如 Serilog)或内置的日志记录系统实现。

示例

public class LoggingMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger<LoggingMiddleware> _logger;     public LoggingMiddleware(RequestDelegate next, ILogger<LoggingMiddleware> logger)
    {
        _next = next;
        _logger = logger;
    }     public async Task InvokeAsync(HttpContext context)
    {
        _logger.LogInformation($"Request: {context.Request.Method} {context.Request.Path}");
        await _next(context);
        _logger.LogInformation($"Response: {context.Response.StatusCode}");
    }
}

自定义中间件

你可以创建自定义中间件来处理特定的需求。自定义中间件通常是一个类,它包含一个 Invoke 或 InvokeAsync 方法,该方法接收 HttpContext 和一个 RequestDelegate 参数。

示例:

public class CustomMiddleware
{
    private readonly RequestDelegate _next;     public CustomMiddleware(RequestDelegate next)
    {
        _next = next;
    }     public async Task InvokeAsync(HttpContext context)
    {
        // 在调用下一个中间件之前执行的操作
        await context.Response.WriteAsync("Custom Middleware: Before\n");         // 调用下一个中间件
        await _next(context);         // 在调用下一个中间件之后执行的操作
        await context.Response.WriteAsync("Custom Middleware: After\n");
    }
}

然后在 Startup.cs 中使用这个中间件:

public void Configure(IApplicationBuilder app)
{
    app.UseMiddleware<CustomMiddleware>();     // 其他中间件
    app.UseRouting();
    app.UseEndpoints(endpoints =>
                     {
                         endpoints.MapGet("/", async context =>
                         {
                             await context.Response.WriteAsync("Hello World!");
                         });
                     });
}

总结

  • 中间件 是 .NET Core 中处理 HTTP 请求和响应的核心组件,它们被组织成一个管道。
  • 中间件的工作原理是:请求依次通过每个中间件,每个中间件可以选择处理请求、传递请求或短路请求管道。
  • 常见的中间件包括身份验证、路由、静态文件服务、异常处理和日志记录。
  • 你可以通过自定义中间件来实现特定的功能。

通过理解中间件的工作原理和常见应用场景,你可以更好地设计和优化 .NET Core 应用程序的请求处理流程。

了解 ASP.NET Core 中的中间件的更多相关文章

  1. 在Asp.net Core中使用中间件来管理websocket

    介绍 ASP.NET Core SignalR是一个有用的库,可以简化Web应用程序中实时通信的管理.但是,我宁愿使用WebSockets,因为我想要更灵活,并且与任何WebSocket客户端兼容. ...

  2. ASP.NET Core 中的中间件

    前言   由于是第一次写博客,如果您看到此文章,希望大家抱着找错误.批判的心态来看. sky! 何为中间件? 在 ASP.NET Framework 中应该都知道请求管道.可参考:浅谈 ASP.NET ...

  3. 在Asp.Net Core中使用中间件保护非公开文件

    在企业开发中,我们经常会遇到由用户上传文件的场景,比如某OA系统中,由用户填写某表单并上传身份证,由身份管理员审查,超级管理员可以查看. 就这样一个场景,用户上传的文件只能有三种人看得见(能够访问) ...

  4. Asp.Net Core 通过自定义中间件防止图片盗链的实例(转)

    一.原理 要实现防盗链,我们就必须先理解盗链的实现原理,提到防盗链的实现原理就不得不从HTTP协议说起,在HTTP协议中,有一个表头字段叫referer,采用URL的格式来表示从哪儿链接到当前的网页或 ...

  5. ASP.NET Core系列:中间件

    1. 概述 ASP.NET Core中的中间件是嵌入到应用管道中用于处理请求和响应的一段代码. 2. 使用 IApplicationBuilder 创建中间件管道 2.1 匿名函数 使用Run, Ma ...

  6. ASP.NET Core 中的那些认证中间件及一些重要知识点

    前言 在读这篇文章之间,建议先看一下我的 ASP.NET Core 之 Identity 入门系列(一,二,三)奠定一下基础. 有关于 Authentication 的知识太广,所以本篇介绍几个在 A ...

  7. [转]ASP.NET Core 中的那些认证中间件及一些重要知识点

    本文转自:http://www.qingruanit.net/c_all/article_6645.html 在读这篇文章之间,建议先看一下我的 ASP.NET Core 之 Identity 入门系 ...

  8. 在ASP.NET Core 中使用Cookie中间件

    在ASP.NET Core 中使用Cookie中间件 ASP.NET Core 提供了Cookie中间件来序列化用户主题到一个加密的Cookie中并且在后来的请求中校验这个Cookie,再现用户并且分 ...

  9. ASP.NET Core中使用GraphQL - 第二章 中间件

    前文:ASP.NET Core中使用GraphQL - 第一章 Hello World 中间件 如果你熟悉ASP.NET Core的中间件,你可能会注意到之前的博客中我们已经使用了一个中间件, app ...

  10. ASP.NET Core 中的SEO优化(2):中间件中渲染Razor视图

    前言 上一篇文章<ASP.NET Core 中的SEO优化(1):中间件实现服务端静态化缓存>中介绍了中间件的使用方法.以及使用中间件实现服务端静态化缓存的功能.本系列文章的这些技巧都是我 ...

随机推荐

  1. mysql重置id排列重新排序

    1.删除表中的原有的主键字段 ALTER TABLE table2 DROP id 2.表中重新创建一个字段 ALTER TABLE table2 ADD id int NOT NULL FIRST; ...

  2. C++之OpenCV入门到提高002:加载、修改、保存图像

    一.介绍 今天是这个系列<C++之 Opencv 入门到提高>得第二篇文章.今天这个篇文章很简单,只是简单介绍如何使用 Opencv 加载图像.显示图像.修改图像和保存图像,先给大家一个最 ...

  3. UniswapV2Factory细节

    UniswapV2Factory合约是Uniswap V2协议中的关键部分,负责管理和创建所有的流动性池(交易对).以下是对UniswapV2Factory合约中所有主要方法及其参数的详细讲解. 方法 ...

  4. 异常断链的惨痛经历!拯救Air780EP模块紧急项目

    ​ 必须要吐槽一下:最近被老板驱使,要用Air780EP模块做几个紧急项目... 就怕紧急项目,时间紧任务重,遇到了一些棘手问题,可把我给折腾死了-- 这里把遇到的问题,排查记录下来,看能不能帮到因遇 ...

  5. Codeforces Round 975 Div.2 C题 解析

    C题 题目链接:Problem - C - Codeforces 题目描述 思路 对于这道题,首先我们能想到最小的组数肯定是数量最多的那个卡片的数量(mx),因为这个值的每一个卡片不能在同一个组里面. ...

  6. MINA 框架简介

    Apache Mina Server 是一个网络通信应用框架,也就是说,它主要是对基于TCP/IP.UDP/IP协议栈的通信框架(然,也可以提供JAVA 对象的序列化服务.虚拟机管道通信服务等),Mi ...

  7. JAVA 注解示例 详解

    注解(Annotation) 为我们在代码中天界信息提供了一种形式化的方法,是我们可以在稍后 某个时刻方便地使用这些数据(通过 解析注解 来使用这些数据). 注解的语法比较简单,除了@符号的使用以外, ...

  8. 源码剖析之sun.misc.Unsafe

    首先介绍一下什么是Compare And Swap(CAS)?简单的说就是比较并交换. CAS 操作包含三个操作数 -- 内存位置(V).预期原值(A)和新值(B).如果内存位置的值与预期原值相匹配, ...

  9. Mybatis【11】-- Mybatis Mapper动态代理怎么写?

    目录 1.回顾Mybatis执行sql的流程 2.mapper动态代理怎么写? 3.mapper动态代理怎么做的? 1.回顾Mybatis执行sql的流程 在之前的代码中我们的运行过程再梳理一下,首先 ...

  10. (系列十四)Vue3+WebApi 搭建动态菜单

    说明 该文章是属于OverallAuth2.0系列文章,每周更新一篇该系列文章(从0到1完成系统开发). 该系统文章,我会尽量说的非常详细,做到不管新手.老手都能看懂. 说明:OverallAuth2 ...