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

其中UseMap函数还提供了对应的分支扩展:UseWhenMapWhenUseMiddleware。下面我们一个个来解释。

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

UseWhenUse的基础上提供了条件分支的功能


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

MapWhenUseWhen类似,都是在请求上下文的基础上去扩展分支,比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. 真正“搞”懂HTTP协议11之代理服务

    代理,其实全称应该叫做代理服务器,它是客户端与服务器之间得中间层,本质上来说代理就是一个服务器,在HTTP的链路中插入的一个中间环节,就是代理服务器啦.所谓的代理服务就是指:服务本身不生产内容,而是处 ...

  2. React Refs-知识点整理记录

    一.Refs的作用 通过Refs,可以访问到 1. DOM节点. 2. render方法中创建的React元素.(class组件的实例) 二.访问节点或者实例有什么用?为什么要使用Refs来访问? 访 ...

  3. 为什么 TCP 建立连接需要三次握手(转载)

    为什么 TCP 建立连接需要三次握手(转载) 原文链接:https://draveness.me/whys-the-design-tcp-three-way-handshake/ TCP 协议是我们几 ...

  4. 使用Hook拦截sendto函数解决虚拟局域网部分游戏联机找不到房间的问题——以文明6为例

    正文 重要提醒(2023-02-13):本文部分内容存在bug,目前正在调试修改,会在一段时间之后更新 重要提醒(2023-02-14):目前已修复主要bug,会在一段时间之后更新,本文计划重写大部分 ...

  5. Istio 升级后踩的坑

    背景 前段时间我们将 istio 版本升级到 1.12 后导致现有的应用监控有部分数据丢失(页面上显示不出来). 一个是应用基础信息丢失. 再一个是应用 JVM 数据丢失. 接口维度的监控数据丢失. ...

  6. idea+git+gitee的使用

    idea+git+gitee的使用 下载git并安装 进入官网,选择合适的版本进行下载: 点击进入官网 下载完毕后,安装git 安装idea中的gitee插件 注意:安装好之后重启idea 进入ide ...

  7. Java刷题常用的数据结构总结

    目录 1. 基础运算 2. 字符串类 3. 数组类与链表 4. 栈和队列 5. 字典类 6. 树 1. 基础运算 //int型相关操作 Integer.INT_MAX;//int型最大值 Intege ...

  8. Luffy项目:2、项目需求(2),项目库的创建,软件开发目录,Django配置文件介绍

    目录 Luffy项目 一.Luffy项目需求(2) 1.后台日志封装 2.全局异常处理.封装 3.封装Response对象 二.Luffy项目数据库创建 1.创建用户数据库 2.使用项目链接数据库 2 ...

  9. C#判断useragent是pc还是手机端

    public static bool CheckAgent(string userAgent) { bool flag = false; string[] keywords = { "And ...

  10. springboot加入cloud,并注册到nacos

    pom.xml下新增 <dependency> <groupId>org.springframework.cloud</groupId> <artifactI ...