ASP.NET Core中的中间件及其工作原理

ASP.NET Core中间件(Middleware)详解:从原理到实战 ASP.NET Core中间件是构建请求处理管道的核心组件,支持多种实现方式(内联匿名中间件、约定风格类和强类型工厂)。它具有比传统HTTP模块更高效的管道式处理架构,通过显式依赖注入和代码优先配置提升了灵活性。开发时可实现基础中间件(如性能监控)和可配置中间件(如自定义CORS),还支持分支管道映射和中间件工厂等高级模式。其类图结构以RequestDelegate为核心,三种实现方式各具特点,分别适用于不同复杂度的场景。 阅读详情

中间件

中间件模式是经典的23中设计模式中的一种,也是.Net Core新引入的一种设计模式。我们在开发项目的过程中会大量的使用中间件。

在ASP.NET Core中,中间件是一个可以处理HTTP请求或响应的软件管道。在ASP.NET Core中,中间件具有非常特定的用途。比如,我们可能需要一个中间件验证用户,一个中间件处理错误,一个中间件来提供静态文件,如Javascript文件、CSS文件和图片等。

我们在ASP.NET Core中使用这些中间件设置请求处理管道,正是这管道决定了如何处理请求。而请求处理管道是由Startup.cs文件中的Configure()方法进行配置的,它也是应用程序启动的一个重要部分。

​ 以下是Congifure()方法中的代码

   // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGet("/", async context =>
                {
                    await context.Response.WriteAsync("Hello World!");
                });
            });
        }

如读者所见,由空项目模板生成的Configure()方法中,有一个非常简单的请求处理管道,其中有3个中间件。

  • UseDeveloperExceptionPage()
  • UseRouting()
  • UseEndpoints()

现在为了更好地了解中间件,我们对代码进行修改,以下是修改后Configure()方法中的代码,有两个中间件。

  public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("Hello World");
            });
        }

通过这个简单的请求处理管道,所有的应用程序都可以将消息写入,然后再由浏览器显示出来。

中间件在ASP.NET Core中的工作原理

如图所示,显示中间以及它们如何适应请求处理管道。

在这里插入图片描述

​ 在ASP.NET Core中,中间件可以同时处理传入请求和传出响应。因此,中间件可以处理传入请求并将该请求传递给管道中的下一个中间件以进行下一步处理。

​ 如果我们有一个日志记录中间件,那么它可能只是记录请求的时间,处理完毕后将请求传递给下一个中间件以进行下一步处理。

​ 终端中间件:该中间件可以处理请求,并决定不调用管道中的下一个中间件,从而使管道短路。微软将其命名为terminal middleware,翻译为终端中间件。短路通常是被允许的,因为它可以避免一些不必要的工作。

​ 如果请求的是一个图片文件或一个CSS纯静态文件,那么StaticFiles中间件可以在处理该请求后,使管道中的其余部分短路。就是说,在图中,如果请求是针对静态文件,则StaticFiles中间件不会调用MVC中间件,从而避免一些无用的操作。

​ 中间件可以通过传入的HTTP请求来响应HTTP请求。比如,管道中的MVC中间件负责处理对URL/students的请求并返回学生列表信息。

​ 中间件还可以处理传出响应。比如,日志记录中间件可以记录响应发送时间。此外,它还可以通过计算接收请求时间和响应时间之间的差异来计算处理请求所花费的时间。

​ 中间件是按照添加到管道的顺序执行的。我们要以正确的顺序添加中间件,否则应用程序可能无法按预期运行。有时候程序虽然会编译成功,但是依然无法正常使用。

​ 在大型团队中,中间件应以NuGet包的形式提供。由NuGet处理更新,通过尽量将中间件拆的足够小,以提供每个中间件独立更新的能力。

​ 在微服务架构中往往设计很多种中间件,大型互联网公司的架构团队会开发各种不同类型的中间件。

​ 在我们的项目中,根据程序需求,可以向请求处理管道添加尽可能多的中间件。如果,我们要使用一些静态HTML页面和图像开发简单的Web应用程序,那么请求处理管道可能只包含StaticFiles中间件。这就是模块化设计的好处,让每个人都像玩积木一样。

​ 另一方面,如果,我们需要开发一个安全的数据驱动设计的Web应用程序,那么可能需要几个中间,如StaticFiles中间件、身份验证中间件、授权中间件和MVC中间件等。

配置ASP.NET Core请求处理管道

我们将使用中间件为ASP.NET Core应用程序配置请求处理管道。

作为应用程序启动的一部分,要在Configure()方法中设置请求处理管道。

 public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("Hello World");
            });
        }
    }

​ 目前的代码有两个中间件在管道中:UseDeveloperExceptionPage()方法和Run()方法。

​ UseDeveloperExceptionPage()中间件:顾名思义,如果存在异常并且环境变量是Development,此中间件会被调用,显示开发异常界面。我们将在以后讨论这个UseDeveloperExceptionPage()中间件和环境变量的配合使用。

​ 第二个中间件是注册Run()方法到管道中,它只能处理信息传入的Response对象。目前,它是一个响应所有请求的中间件,返回“Hello World“。在这种情况下,无论请求路径是什么,所有请求都会被这个中间件处理,我们得到的返回值都是这个中间件调用Response对象返回的string类型的字符串。

​ 请注意,返回的值是纯文本而不是HTML。我们可以通过检测页面源代码来确认这一点。可以看到,源代码中没有任何HTML标签,只是纯文本。

​ 即使现在创建一个html文件,并且在请求中包含该文件的路径:http://localhost:5000/index.html,应用程序也无法返回该静态文件。这是因为目前我们的请求处理管道中没有可以提供静态文件的中间件,所以不支持HTML、图像、CSS和Javascript等文件的显示。在后面的内容中,我们将添加所需的中间件以便能够提供静态文件。

Configure()代码解析

 app.Run(async (context) =>
            {
                await context.Response.WriteAsync("Hello World");
            });

关于这段代码的解析如下:

  • 我们调用Run()方法添加中间件到请求处理管道中
  • 如果将鼠标悬停在Run()方法上,则可以从智能提示中看到Run()方法是作为IApplicationBuilder接口的扩展方法实现的。这就是我们能够在IApplicationBuilder对象应用程序上调用此Run()方法的原因。

在这里插入图片描述

  • 传递给Run()方法的参数是一个RequestDelegate,我们可以从智能提示中看到它。
  • RequestDelegate是一个作为HttpContext对象的参数委托
  • 通过这个HttpContext对象,中间件可以访问传入的HTTP请求和传出的HTTP响应。
  • 目前,我们使用Lambda将请求进行传递,因为Lambda通过委托内联的方式作为匿名方法传递,所以Lambda表达式是一种特殊的委托。
  • 使用Run()扩展方法,只能将一个在终端中间件添加到请求管道。
  • 终端中间件会使管道短路,而不会去调用下一个中间件。

中间件掌握测试

  app.Run(async (context) =>
            {
                context.Request.ContentType = "text/plain;charset=utf-8";
                await context.Response.WriteAsync("从第一个中间件中打印Hello World");
            });

            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("从第二个中间件中打印Hello World");
            });

以上中间件的输出结果(在此未放结果截图)说明如下:

  • 我们使用Run()方法注册了两个中间件。
  • 运行此项目时,我们只看到了第一个中间件的响应有返回值。
  • 第二个中间件没有响应。
  • 这是因为使用Run()方法注册的中间件无法调用管道中的下一个中间件。
  • 使用Run()方法注册的中间件是终端中间件。

中间件传递

如果希望中间件能够调用管道中的下一个中间件,则应注册Use()中间件,如下所示:

 app.Use(async (context, next) =>
            {
                await next();
            });

            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("从第二个中间件中打印Hello World");
            });

注意,Use()方法有两个参数。第一个参数是HttpContext上下文对象;第二个参数是Func类型,即它是代表管道中下一个中间件的委托。

实践中间件的工作流程

接下来看一看实践中间件的工作流程

  public void Configure(IApplicationBuilder app, IWebHostEnvironment env,ILogger<Startup> logger)
        {
            app.Use(async (context, next) =>
            {
                logger.LogInformation("MW1:传入请求");
                await next();
                logger.LogInformation("MW1:传出响应");
            });

            app.Use(async (context, next) =>
            {
                logger.LogInformation("MW2:传入请求");
                await next();
                logger.LogInformation("MW2:传出响应");
            });

            app.Use(async (context, next) =>
            {

                await context.Response.WriteAsync("MW3:处理请求并生成响应");
                logger.LogInformation("MW3:处理请求并生成响应");
            });
        }

代码说明如下:

  • ILogger服务被注入Configure()方法中,用于日志的记录
  • 项目启动时,Main()方法调用CreateDefaultBuilder()配置日志记录

读者可以通过查看ASP.NET Core 3.1在Github的源代码来验证这一点。

  • 检查文件中ConfigureLogging()方法,读者会发现,ILogger配置了AddConfiguration、Console、Debug和EventSource。
.ConfigureLogging((hosting,logging)=>
{
 logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
 logging.AddConsole();
 logging.AddDebug();
 logging.AddEventSourceLogger();
}).

代码说明如下:

  • 我们使用依赖注入的方式将ILogger记录到系统中

  • 如果使用.NET Core CLI运行项目,则可以在控制台窗口中查看记录的信息。

  • 如果直接在Visual Studio上运行项目,则可以在输出窗口中查看记录的信息。

  • 我们将看到,信息按以下顺序记录着

    • MW1:传入请求
    • MW2:传入请求
    • MW3:处理请求并生成响应
    • MW2:传出响应
    • MW1:传出响应

在这里插入图片描述

将输出结果与下图所示的内容结和起来理解
在这里插入图片描述

  • 请记住,ASP.NET Core中的中间件可以处理传入请求和传出响应
  • 请求先到达Middleware1,它记录传入请求,因此我们首先看到此消息
  • Middleware1调用next()方法,next()方法会调用管道中的Middleware2
  • Middleware2记录传入请求
  • Middlew2会调用next()方法,next()方法再调用Middleware3
  • Middleware3处理请求并生成响应。
  • 此时请求处理流程在管道中开始反向传递
  • Middleware3将控制权交回到Middleware2,并将Middleware3生成的响应值(处理请求并生成响应)传递给它。Middleware2记录传出响应,这是我们接下来看到的。
  • Middleware2将控制权交给Middleware1
  • Middleware1记录传出响应,这是我们最后看到的。

总结

ASP.NET Core的中间件有以下特点:

  • 可同时被访问和请求
  • 可以处理请求,然后将请求传递给下一个中间件
  • 可以处理请求,并使管道短路
  • 可以处理传出响应
  • 中间件是按照添加的顺序执行的。

中间件的工作流程如下:

  • 所有的请求都会在每个中间件调用next()方法之前触发。请求按照一定方向依次穿过所有管道
  • 当中间件处理请求并产生响应时,请求处理流程在管道中开始反向传递
  • 所有的响应都会在每个中间件调用next()方法之前触发。响应按一定方向依次穿过所有管道。
ASP.NET Core 中间件深度解析:构建灵活高效的请求处理管道 在现代Web应用开发中,请求处理管道的设计和实现至关重要。ASP.NET Core通过其中间件(Middleware)系统提供了一种高度灵活、可扩展的方式来构建请求处理管道。本文将全面深入地探讨ASP.NET Core中间件的概念、工作原理、实现方式以及最佳实践,帮助开发者掌握这一核心技术。 阅读详情

相关推荐

ASP .NET Core 的运行机制和启动(转)

ASP .NET Core 的运行机制和启动

ppp17的博客 2307

将 HTTP 处理程序和模块迁移到 ASP.NET Core 中间件

本文摘自Asp.Net Core的官方文档,是很好的了解HttpModule、HttpHandler、中间件MiddleWare、IOptions的渠道。 本文介绍如何将现有的 ASP.NET HTTP 模块和处理程序从 system.webserver迁移到 ASP.NET Core中间件。 模块和处理程序被 在继续 ASP.NET Core 中间件之前,让我们先回顾一下 HTTP 模块和处理程序的工作原理: 处理程序是: 实现IHttpHandler的类 用于处...

carcarrot的博客 698

了解 ASP.NET Core 中的中间件

中间件是HTTP 请求管道中的一个处理单元,负责处理传入的 HTTP 请求和返回的 HTTP 响应。处理请求:可以对请求进行预处理(如修改请求内容、验证身份等)。决定是否继续传递请求:可以选择将请求传递给下一个中间件,或者直接返回响应(短路请求管道)。处理响应:可以在响应返回给客户端之前进行后处理(如添加响应头、记录日志等)。你可以创建自定义中间件来处理特定的需求。自定义中间件通常是一个类,它包含一个Invoke或方法,该方法接收和一个参数。中间件。

weixin_60669486的博客 1362

ASP.NET Core基本原理(2)-中间件

什么是中间件中间件是装配到应用管道中用来处理请求和响应的软件组件。管道中的每一个组件都可以选择是否将请求移交给下一个组件,并且可以在管道中调用下一个组件之前或者之后执行指定的操作。请求委托被用于构建请求管道。请求委托会处理每一个HTTP请求。请求委托通过在传递给Startup类中的Configure方法的IApplicationBuilder类型上使用Run,Map,Use扩展方法进行配置。一个单独的请求委托可以被指定为一个内嵌的匿名方法,或定义在一个可重用的类中。

qq_39173779的博客 378

别再用Excel硬算传热了!用MATLAB/Octave复现国赛数学建模A题(附完整代码与避坑指南)

本文详细介绍了如何利用MATLAB/Octave高效解决数学建模中的传热问题,替代传统的Excel计算方法。通过复现2018年国赛A题的高温作业服传热模型,从理论推导到代码实现,提供了完整的有限差分法解决方案和参数拟合技巧,帮助读者提升数学建模效率和准确性。

weixin_30512965的博客 377

相机基础知识讲解:CMOS和CCD

相机基础知识讲解:CMOS和CCD

Coppa的博客 5万+

ASP.NET Core 中间件(二)

Asp.Net和Asp.Net Core管道的区别 了解了中间件的实现过程后,小妹在反思一个问题,为什么要使用中间件?他的作用是什么? 经过面向百度编程,了解到原有ASP.NET应用升级到ASP.NET Core的过程中,会遇到一个新的概念:中间件。中间件是ASP.NET Core全新引入的概念。中间件是一种装配到应用管道中以处理请求和响应的软件。 每个组件选择是否将请求传递到管道中的下一个组件、可在管道中的下一个组件前后执行工作。单独看以上中间件的定义,一个很直观的感觉:中间件是HTTP请求管道中的一层

huqngqing的博客 328

免安装版Notepad++终极配置:右键菜单+图标美化+多文件批量处理(2024新版)

本文详细介绍了如何为免安装版Notepad++进行终极配置,包括右键菜单添加、图标美化以及多文件批量处理功能。通过注册表编辑和高级定制,用户可以在便携版中实现与安装版相同的功能体验,同时保持系统整洁。特别适合开发者、系统管理员和效率追求者使用。

nut55的博客 830

细说ASP.NET Core与OWIN的关系

前言   最近这段时间除了工作,所有的时间都是在移植我以前实现的一个Owin框架,相当移植到到Core的话肯定会有很多坑,这个大家都懂,以后几篇文章可能会围绕这个说下,暂时就叫《Dotnet Core踩坑记》吧,呵呵。   接下来我对我在移植过程中发现的一些问题进行了总结,今天主要说说Owin。说到Owin就不能不提Katana项目和宇内大神的Tinyfox了,当然关于这两

dotNET跨平台 1974

Ubuntu离线情况下安装gcc编译器

Ubuntu离线情况下安装gcc编译器1.系统版本2.安装说明3.异常处理 1.系统版本 (1)Ubuntu系统版本:20.04.1LTS; (2)gcc编译器版本:gcc-9.3.0(下载链接为https://download.csdn.net/download/qq_18350351/13762214); 当前可找到的gcc最新版本为gcc-10,但是笔者在安装gcc-10版本时发现一些依赖项无法安装,因此选取了gcc-9版本。如果是在联网情况下安装,直接使用apt相关的安装指令即可。 2.安装说明 安

GreenHand的博客 3932

hpm6750evk2开发板(四)TCP回送(1000M网口)

再接下来我们修改代码,先找到配置网速的地方,肯定是在enet的初始化函数里面,我们一个函数一个函数找,也可以用单步调试一步一步找,结果发现是在enet_init函数里面调用的rtl8211_basic_mode_default_config函数配置网速的,我们把enet_phy_port_speed_100mbps改为enet_phy_port_speed_1000mbps,重新编译运行试试。首先我们复制一份lwip_tcpecho代码,重命名为lwip_tcpecho_RGMII,如下图所示。

Silas1750的博客 919

c# .net core中间件,生命周期

c# .net core中间件,生命周期

橙-极纪元-JJYCheng 1729

WorldPop数据集

WorldPop数据集介绍

qq_43874102的博客 1万+

ASP.NET Core 中间件

中间件是一种装配到应用管道以处理请求和响应的软件。 每个组件: 1.选择是否将请求传递到管道中的下一个组件。 2.可在管道中的下一个组件前后执行工作。 请求委托用于生成请求管道。 请求委托处理每个 HTTP 请求。 使用 Run 、Map 和 Use 扩展方法来配置请求委托。 可将一个单独的请求委托并行指定为匿名方法(称为中间件),或在可重用的类中对其进行定义。 这些可重用的类和并行匿名方法即为中...

zhoubangbang1的博客 469

[QMT和ptrade量化交易小白入门]-125、菜场大妈加上四大现金行业指数风控,最大回撤从22%减少了一半

群里面有人建议,在菜场大妈策略的基础上,加入申万的行业指数(银行,钢铁,有色,煤炭)测算其宽度,当这四大行业其中有一个高就会清仓(用来控制回撤)。这背后的逻辑是,在存量资金博弈的市场环境中,资金总量相对固定,当银行、钢铁、有色、煤炭等大市值周期行业因基本面改善(如涨价、政策催化)或避险需求而走强时,会吸引大量资金涌入,导致其他板块(尤其是小市值股票)面临流动性虹吸。经过回测,对比上一个版本发现确实是可以降低一半的回撤,最大回撤从22.3%降到了11.4%,而且有很多时间是空仓等待。

木头大左的博客 237

SAP FICO CBS接口-银企直连付款平台功能开发说明书(包括测试样例、FS)

SAP FICO CBS接口-银企直连付款平台功能开发说明书(包括测试样例、FS)

我好像病了的博客 2447

asp怎么插入图片_ASP.NET Core 中的中间件

ASP.NET Core 中的中间件(Middleware)在这个节中,我们将了解,ASP.NET Core 中的中间件是 什么?中间件很重要,尤其是在你想当架构师这一条路上。ASP.NET Core 中的中间件是 什么?在 ASP.NET Core 中,中间件(Middleware)是一个可以处理 HTTP 请求或响应的软件管道。 ASP.NET Core 中给中间件组件的定位是具有非常特定的用...

weixin_42553471的博客 380

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Asp.Net Core 系列教程 (四) 消息中间件

在ASP.Net Core 添加了诸多的“中间件”处理用户的请求和响应,这种方式非常编译功能扩展,如果我需要修改某个功能时 直接添加对应的中间件就好了,不需要 大规模的调整架构了。 当然再好的架构都有其弊端。 矛盾存在于一切事物,并贯穿于事物发展的始终。 好了,言归正传 消息中间件的原理 先看下面的代码 public void Configure(IApp...

隔壁王叔叔 2864

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

asp css怎么写?_ASP.NET Core 中的中间件

http://ASP.NET Core 中的中间件(Middleware)在这个节中,我们将了解,http://ASP.NET Core 中的中间件是 什么?中间件很重要,尤其是在你想当架构师这一条路上。http://ASP.NET Core 中的中间件是 什么?在 http://ASP.NET Core 中,中间件(Middleware)是一个可以处理 HTTP 请求或响应的软件管道。 http...

weixin_30746067的博客 139

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

排课系统asp源代码_ASP.NET Core中HTTP管道和中间件的二三事

本文出自《从零开始学ASP.NET CORE MVC》推荐文章:中间件是什么?在.NETCore中的工作原理又是怎样的呢?配置ASP.NET Core请求(Request)处理管道在本视频中,我们将讨论使用中间件组件为asp.netcore应用程序配置请求处理管道。作为应用程序启动的一部分,我们要在Configure()方法中设置请求处理管道。public class Startu...

weixin_36078790的博客 106

排课系统asp源代码_ASP.NET Core中HTTP管道和中间件的二三事11

本文出自《从零开始学ASP.NET CORE MVC》推荐文章:中间件是什么?在.NETCore中的工作原理又是怎样的呢?配置ASP.NET Core请求(Request)处理管道在本视频中,我们将讨论使用中间件组件为asp.netcore应用程序配置请求处理管道。作为应用程序启动的一部分,我们要在Configure()方法中设置请求处理管道。public class Startu...

weixin_35919843的博客 141

ASP.NET Core3.1 中间件middleware说明

参考网址:http://www.zyiz.net/tutorial/detail-4543.html https://docs.microsoft.com/zh-cn/dotnet/api/microsoft.aspnetcore.builder?view=aspnetcore-3.1 中间件是一种装配到应用管道以处理请求和响应的软件。每个组件: 选择是否将请求传递到管道中的下一个组件。 ...

沐雪架构师 1715

15.ASP.NET Core 应用程序中的静态文件中间件

在这篇文章中,我将向大家介绍,如何使用中间件组件来处理静态文件。这篇文章中,我们讨论下面几个问题:在ASP.NET Core中,我们需要把静态文件存放在哪里?在ASP.NET Core中 wwwroot文件夹是啥?怎样在ASP.NET Core应用程序中,配置静态文件中间件?UseFileServer中间件的作用是什么? 最重要的特性之一就是;几乎所有的web应用程序都应该具备直接从文件系统存取静态文件的能力。ASP.NET Core能够直接从客户端获取应用程序的静态文件,比如:HTML、I...

zhoumouren88的博客 432
上一篇: Git起步—关于Git
下一篇: 安装、配置Git
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值