在Asp.Net Core中,管道往往伴随着请求一起出现。客户端发起Http请求,服务端去响应这个请求,之间的过程都在管道内进行。

举一个生活中比较常见的例子:旅游景区。

我们都知道,有些景区大门离景区很远,我们需要经过层层关卡才能到达景区。

我的请求最终就是去到景区,去到景区的整个过程就是管道,景区就是服务器,层层关卡就是一个个中间件了,比如:门票、停车费、摆渡费等等。

如果其中任何一个中间件卡壳了,比如我没买门票,那别人肯定是不让我进去,这就是管道短路了。


Asp.Net Core 请求管道包含一系列Http请求委托(RequestDelegate),依次调用。

微软给的图示:

.Net Core服务

在解释管道的使用方法之前,我们先来准备一个Asp.Net Core服务。

创建一个.Net Core控制台应用程序,并实现如下代码,一个简单的使用 Kestrel 托管的服务就完成了:


internal class Program{ static void Main(string[] args) { new WebHostBuilder() .UseKestrel() .UseStartup<Startup2>() .Build() .Start();
Console.ReadLine(); }}public class Startup{ public void Configure(IApplicationBuilder app) { }}

 

这也是.Net Core的优点之一,只选择我们需要的,摒弃那些多余的功能。优点是优点,一般开发中也犯不上这样去做。

Kestrel 托管默认监听端口:5000

管道中间件

微软这边内置了三个扩展函数供我们构建自己的中间件:

  1. Use

  2. Map

  3. Run

其中Use和Map函数还提供了对应的分支扩展:UseWhen、MapWhen、UseMiddleware。下面我们一个个来解释。

app.Use

Use 是最常用的一种模式,承接上一个请求并执行下一个请求的任务


public void Configure(IApplicationBuilder app){ app.Use(async (context, next) => { Console.WriteLine("middleware1"); await next.Invoke(); }); app.Use(async (context, next) => { Console.WriteLine("middleware2"); });}

app.UseWhen

UseWhen在Use的基础上提供了条件分支的功能


app.UseWhen(context => // 判断请求路径的开头是否是/h context.Request.Path.StartsWithSegments(new PathString("/h")), c => c.Use(async (context, next) => { Console.WriteLine("middleware1"); await next.Invoke(); }));app.Use(async (context, next) =>{ Console.WriteLine("middleware2");});

 

app.Map

Map我们可以理解成专为请求路径扩展的分支中间件,可以根据请求路径去处理对应分支逻辑,与上面的UseWhen例子效果类似,但更加方便。


app.Map("/h", _app =>{ _app.Use(async (context, next) => { Console.WriteLine("hello world"); });});

app.MapWhen

MapWhen与UseWhen类似,都是在请求上下文的基础上去扩展分支,比Map更加灵活。

app.MapWhen(context => { return context.Request.Query["name"] == "tony"; }, _app => {    _app.Use(async (context, next) => {        context.Response.ContentType = "text/plain; charset=utf-8";        await context.Response.WriteAsync("i 服了 you");    });});

app.Run

Run一般用于断路或请求管道的末尾,不会将请求传递下去

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

UseMiddleware

将一个完整的类添加到管道中间件,也就是将上面的请求委托,用类以及函数的形式替代了,便于我们的代码管理。

app.UseMiddleware<DotnetboyMiddleware>();
public class DotnetboyMiddleware{ private readonly RequestDelegate _next; private readonly string _name; public DotnetboyMiddleware(RequestDelegate next, string name) { _next = next; _name = name; } public Task Invoke(HttpContext context) { context.Response.WriteAsync($"my name is {_name}").Wait(); return this._next(context); }}

微软内置的一些管道中间件扩展函数就介绍完了,下面我们实现一下微软实例图示中的效果:

public void Configure(IApplicationBuilder app){    app.Use(async (context, next) =>    {        Console.WriteLine("middleware1 : in");        await next.Invoke();        Console.WriteLine("middleware1 : out");    });    app.Use(async (context, next) =>    {        Console.WriteLine("middleware2 : in");        await next.Invoke();        Console.WriteLine("middleware2 : out");    });    app.Run(async context =>    {        Console.WriteLine("Hello World");        await context.Response.WriteAsync("Hello World");    });}

从上面的例子中我们可以看到,中间件都是由上而下依次执行,由每个中间件决定是否继续执行下一个中间件,最终到响应结果。

如果哪个中间件决定不往下执行,那通道也就短路了,比如我们去掉 middleware2 的 await next.Invoke();

执行到 Console.WriteLine("middleware2 : out"); 就短路了,此路不通,原路返回。

因为管道中间件执行逻辑的关系,我们在实际开发中要注意两点:

  • 1、谨慎使用管道短路

  • 2、注意中间件的使用顺序,比如:路由中间件肯定是要在认证中间件前面执行,有中间件需要访问文件,在此之前就必须先执行开放静态文件的中间件

.NET Core基础:白话管道中间件的更多相关文章

  1. .NET Core基础篇之:白话管道中间件

    在.Net Core中,管道往往伴随着请求一起出现.客户端发起Http请求,服务端去响应这个请求,之间的过程都在管道内进行. 举一个生活中比较常见的例子:旅游景区. 我们都知道,有些景区大门离景区很远 ...

  2. Asp.Net Core基础篇之:白话管道中间件

    在Asp.Net Core中,管道往往伴随着请求一起出现.客户端发起Http请求,服务端去响应这个请求,之间的过程都在管道内进行. 举一个生活中比较常见的例子:旅游景区. 我们都知道,有些景区大门离景 ...

  3. Core 1.0中的管道-中间件模式

    ASP.NET Core 1.0中的管道-中间件模式 SP.NET Core 1.0借鉴了Katana项目的管道设计(Pipeline).日志记录.用户认证.MVC等模块都以中间件(Middlewar ...

  4. ASP.NET Core 中间件 - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core 中间件 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 中间件 上一章节中,我们我们有讲到 Startup 类中的 Confi ...

  5. ASP.NET Core 1.0中的管道-中间件模式

    ASP.NET Core 1.0借鉴了Katana项目的管道设计(Pipeline).日志记录.用户认证.MVC等模块都以中间件(Middleware)的方式注册在管道中.显而易见这样的设计非常松耦合 ...

  6. .net core 基础知识

    1.IOC(转:https://www.cnblogs.com/artech/p/inside-asp-net-core.html) IoC的全名Inverse of Control,翻译成中文就是“ ...

  7. ASP.NET Core Identity 配置 - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core Identity 配置 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core Identity 配置 上一章节我们简单介绍了下 Id ...

  8. ASP.NET Core 静态文件 - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core 静态文件 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 静态文件 前几章节中,我们学习了 ASP.NET Core 的中间件 ...

  9. ASP.NET Core 异常和错误处理 - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core 异常和错误处理 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 异常和错误处理 上一章节中,我们学习了 ASP.NET Cor ...

  10. ASP.NET Core 项目配置 ( Startup ) - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core 项目配置 ( Startup ) - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 项目配置 ( Startup ) 前面几章节 ...

随机推荐

  1. 导出excel类型转换

    Map headmap = new LinkedHashMap<String, String>(); headmap.put("createtime", "日 ...

  2. 【一句话】Thread.sleep(0)的作用

    首先一句话: 在循环中加入Thread.sleep(0),用于在循环中放入safepoint,JVM进行STW,然后触发GC. 详细: 说白了,它的作用就是给可数(int控制)循环加入safepoin ...

  3. spring-in-action-初识反应式编程reactor

    一:反应式编程 1.反应式编程的优点 1)无阻塞 2)处理的数据可以是无限的 打水仗:  命令式编程:使用的是水气球.水气球的容量有限.把水气球装水,再扔向对方.如果想要更多的水,就需要更多的水气球. ...

  4. STM32F0_HAL初始化系列:FLASH写入

    //读 read_temp = *(__IO uint32_t*)value_address; //写 static void flash_write(uint32_t address, uint32 ...

  5. WAVE音频文件格式及其64位扩展格式的简要介绍

    正文 关于 WAVE 文件格式,网上有不少介绍,但关于WAVE 64位扩展格式的介绍却是几乎没有. 所以本文的目的是简要介绍标准的 WAVE 格式,以及两种主要的扩展格式. 文中所有代码都用C语言来描 ...

  6. day13-自定义拦截器

    自定义拦截器 1.什么是拦截器 说明: 拦截器与过滤器的区别 SpringMVC 的拦截器(Interceptor)与 Java Servlet 的过滤器(Filter)类似,它主要用于拦截用户的请求 ...

  7. 使用vscode编辑markdown

    目录 markdown在vscode中的使用 标题 一级标题 二级标题 三级标题 四级标题 五级标题 六级标题 列表 图片 表格 网址 代码 文本样式 引用 目录 vscode中使用的插件推荐 截图工 ...

  8. npm+react linux 开荒

    安装npm 从 https://nodejs.org/dist/ 找到下载包,并不是版本越高越好,得看项目的需要. 解压之后,将解压路径bin添加到PATH里. 完成后可配置npm源 npm inst ...

  9. Ubuntu 安装 Nginx

    Ubuntu版本:20.04.1 LTS Nginx版本:1.22.0 下载地址: https://nginx.org/en/download.html 上传目录:/usr/local/src 安装目 ...

  10. pdf.js 跨域完美解决!

    在网上查看很多方法去解决此类跨域问题,及如何动态加载pdf文件.看来看去 请求的由后台处理加header头的  pdf.js 自带的 获取地址栏param参数值的 都是很麻烦的步骤并且有时不能有效解决 ...