ASP.NET Core - 哀求管道与中心件

来自版块: 资讯
106
1

1.哀求管道哀求管道是什么?哀求管道形貌的是一个哀求进到昨们的后端应用,后端应用怎样处置惩罚的过程,从吸收到哀求,之后哀求怎么流转,颠末哪些处置惩罚,末了怎么返反响应。哀求管道就是一次哀求在后端应用的生 ...

1. 哀求管道

哀求管道是什么?哀求管道形貌的是一个哀求进到昨们的后端应用,后端应用怎样处置惩罚的过程,从吸收到哀求,之后哀求怎么流转,颠末哪些处置惩罚,末了怎么返反响应。哀求管道就是一次哀求在后端应用的生命周期。相识哀求管道,有助于昨们明确后端应用是怎么工作的,昨们的代码是怎么工作的,在昨们的业务代码实行前后颠末哪些步调,有助于昨们之后更好的实现一些AOP操纵。

哀求管道是 .net 应用的一个最根本的概念。在 .net core 中,微软对框架底层举行了全新的计划,相对于本来的ASP.NET中的百口桶模式的管道模子,.net core的管道模子更加机动便捷,可做到热插拔,通过管道可以随意注册本身想要的服务大概第三方服务插件,这也是.net core性能更好的缘故原由。

以上是微软官方文档中的管道模子图。从图中可以看到 服务器吸收到哀求之后,将吸收到的哀求向后通报,依次颠末一个个 Middleware 举行处置惩罚,然后由末了一个 MiddleWare 天生相应内容并回传,再反向依次颠末每一个 Middleware,直到由服务器发送出去。整个过程就像一条流水线一样,管道这个词是很形象的,而 Middleware 就像一层一层的“滤网”,过滤全部的哀求和相应。

2. 中心件

管道之中,对哀求、相应举行加工处置惩罚的模块是 Middleware,也就是中心件。中心件本质上是一个委托。

2.1 工作模式

从上面的图可以看出,每一个中心件都会被实行两次,在下一个中心件实行之前和之后各实行一次,分别是在处置惩罚哀求和处置惩罚相应,只有一个中心件是破例的,那就是末了一个中心件,它背面没有下一个中心件,以是实行到它管道就会回转。

这代表了中心件的两种工作模式,也是中心件的两种根本注册方式。中心件本质上是一个委托,在代码实现上就表现在委托的入参有所差别以及注册调用的方法差别。

中心件两种最根本的注册方式:

  • Use 方法注册use 注册的中心件会传入next参数,在处置惩罚完自己的逻辑之后可以调用 next() 去实行下一个中心件假如不实行,就即是Run
  • Run 方法注册Run 只是实行,没有去调用Next ,一样平常作为闭幕点。Run 方法注册,只是一个扩展方法,终极照旧调用Use方法

在代码中分别是以下方式:

app.Use(async (context, next) =>
{
    await context.Response.WriteAsync("Hello Middlerware !");
    if(context.Request.Query.TryGetValue("query", out var query))
    {
        await context.Response.WriteAsync(query);
    }
    await next();
    await context.Response.WriteAsync("End Middleware !");
});

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

末了的实行效果如下,也可以从代码实行的先后次序看出管道活动的次序。当前中心件手动调用 next() 之后,就进入下一个中心件,下一个中心件处置惩罚完成之后,按照管道的次序再一个一个回传。在这个过程中不停稳定,被管道通报的就是HttpContext,而昨们拿到 HttpContext,即可以通过 Request 和 Response 对当前这一次的哀求做任何处置惩罚了。

通太过析asp.net core的源码,可以看到在昨们调用 Run() 的时间,现实上照旧调用了 Use() 方法。

而 Use() 方法中,重要的逻辑仅仅只是将相应的委托存放到聚集中

之后在 build 方法调用的时间才一个一个地调用中心件委托。

除了上面的 Use() 、Run() 两个最根本的方法注册中心件之外,另有别的一些方法,如通过 Map() 方法注册中心件,这种方式会创建一个新的管道分支,在路由满意Map的规则时,哀求则转型新的管道分支,末了沿着管道分支返反响应,而不走原有的管道。

app.Use(async (context, next) =>
{
    await context.Response.WriteAsync("Hello Middlerware1 ! ");
    if(context.Request.Query.TryGetValue("query", out var query))
    {
        await context.Response.WriteAsync(query);
    }
    await next();
    await context.Response.WriteAsync("End Middleware1 ! ");
});

app.Map("/map", app =>
{
    // map方法中的委托,传入的时IApplicationBuilder, 在这里相称于一个新的管道,也可以和主管道一样举行恣意操纵
    app.Run(async context =>
    {
        await context.Response.WriteAsync("Hello map Middleware pipeline ! ");
    });
});

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

实行效果如下:

其他的分支管道创建方式,如 MapWhen,和 Map 大同小异,只是对于匹配判定的方式有所差别。像微软内置中心件中的静态文件中心件,MVC 中心件,实在都是以分支管道的方式实现的,一旦匹配到哀求就会走管道分支。

2.2 中心件的利用设置

利用一个中心件必要在 .net core 的入口文件中举行设置,假如是 .net 6版本,那只要在 program.cs 文件中举行设置即可,通过 WebApplication 对象,也就是 app 调用相干的方法。

假如是 .net 6 以下版本,可以在 startup.cs 文件中的 Configure 方法中设置。.net 6 与之前版本入口文件的差别上一篇文章也讲过,这里就不赘述了。

这里可以看得到,一些中心件的调用并没有直接利用 Use() 和 Run(),究竟将各个中心件的处置惩罚逻辑全部放在入口文件很欠好管理,而且也很不优雅。这里涉及到了中心件封装的约定规则,一样平常环境下封装一个中心件都会提供一个 Use[Middleware] 方法以供利用者举行中心件的调用,WebApplication 对象的 UseXXX 方法都是中心件调用的方法。

2.3 ASP.NET Core 框架内置中心件

ASP.NET Core 框架之中内置有许多中心件,而且昨们通过 VS 创建某一个范例的项目时,如MVC、Razor Page,初始化的项目代码中会帮昨们设置好一些中心件。

以上为官方文档中列出的内置中心件,可以看到在列表中对每个中心件的次序举行了阐明。

管道中的中心件分列是有先后之分的,哀求和相应按照中心件的分列次序举行通报,这也是昨们代码逻辑实行的次序,而且一些中心件必要依靠于其他中心件的处置惩罚效果,大概必须在某些中心件前先实行,否则就会出题目了。

而中心件插入到管道中的次序,就是依据昨们在入口文件中调用相应中心注册方法的次序,以是代码的前后次序非常紧张,一旦写错了就会出现许多意想不到的的Bug。

向 Program.cs 文件中添加中心件组件的次序界说了针对哀求调用这些组件的次序,以及相应的相反次序。 此次序对于安全性、性能和功能至关紧张。这是官方文档中的原话。

官方文档给出了典范MVC应用的管道中心件次序,这里实在不止MVC,Razor Page、Web Api 也是如许的管道模子,如下图。这里也明白了昨们自界说的中心件应该插入到哪个位置。

更多的内置中心件的作用,以及相应的管道次序要求,请具体阅读一下官方文档,这里就不细说了。


路过

雷人

握手

鲜花

鸡蛋
看帖是喜欢,评论才是真爱:

全部回复(1)

我要评论
2025-8-11 10:38

热文

  • 3 天
  • 7天
返回顶部