.NET Core基础:白话管道中间件
在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
管道中间件
微软这边内置了三个扩展函数供我们构建自己的中间件:
Use
Map
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基础:白话管道中间件的更多相关文章
- .NET Core基础篇之:白话管道中间件
在.Net Core中,管道往往伴随着请求一起出现.客户端发起Http请求,服务端去响应这个请求,之间的过程都在管道内进行. 举一个生活中比较常见的例子:旅游景区. 我们都知道,有些景区大门离景区很远 ...
- Asp.Net Core基础篇之:白话管道中间件
在Asp.Net Core中,管道往往伴随着请求一起出现.客户端发起Http请求,服务端去响应这个请求,之间的过程都在管道内进行. 举一个生活中比较常见的例子:旅游景区. 我们都知道,有些景区大门离景 ...
- Core 1.0中的管道-中间件模式
ASP.NET Core 1.0中的管道-中间件模式 SP.NET Core 1.0借鉴了Katana项目的管道设计(Pipeline).日志记录.用户认证.MVC等模块都以中间件(Middlewar ...
- ASP.NET Core 中间件 - ASP.NET Core 基础教程 - 简单教程,简单编程
原文:ASP.NET Core 中间件 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 中间件 上一章节中,我们我们有讲到 Startup 类中的 Confi ...
- ASP.NET Core 1.0中的管道-中间件模式
ASP.NET Core 1.0借鉴了Katana项目的管道设计(Pipeline).日志记录.用户认证.MVC等模块都以中间件(Middleware)的方式注册在管道中.显而易见这样的设计非常松耦合 ...
- .net core 基础知识
1.IOC(转:https://www.cnblogs.com/artech/p/inside-asp-net-core.html) IoC的全名Inverse of Control,翻译成中文就是“ ...
- ASP.NET Core Identity 配置 - ASP.NET Core 基础教程 - 简单教程,简单编程
原文:ASP.NET Core Identity 配置 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core Identity 配置 上一章节我们简单介绍了下 Id ...
- ASP.NET Core 静态文件 - ASP.NET Core 基础教程 - 简单教程,简单编程
原文:ASP.NET Core 静态文件 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 静态文件 前几章节中,我们学习了 ASP.NET Core 的中间件 ...
- ASP.NET Core 异常和错误处理 - ASP.NET Core 基础教程 - 简单教程,简单编程
原文:ASP.NET Core 异常和错误处理 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 异常和错误处理 上一章节中,我们学习了 ASP.NET Cor ...
- ASP.NET Core 项目配置 ( Startup ) - ASP.NET Core 基础教程 - 简单教程,简单编程
原文:ASP.NET Core 项目配置 ( Startup ) - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 项目配置 ( Startup ) 前面几章节 ...
随机推荐
- 打开sublime text3 弹出错误提示 Error trying to parse settings: Expected value inPackages\UserJSONsublime-settings:13:17
问题:打开sublime text3 弹出错误提示 Error trying to parse settings: Expected value inPackages\UserJSONsublime- ...
- JSP第五次作业
1.教材P78-79 例4-9 1 <%@ page language="java" import="java.util.*" pageEncoding ...
- drf-序列化字段及参数、序列化和反序列化高级用法、ModelSerializer使用
1.序列化类常用字段和字段参数 1.1 常用字段类 1.BooleanField 2 NullBooleanField 3 CharField CharField(max_length=None, m ...
- 【一句话】Java8后abstract class和interface的区别
首先一句话: Java8后(1)interface支持default和static方法有实现,abstract class依然是抽象方法和非抽象方法,(2)可同时实现多个interface,(3)但成 ...
- ubuntu apt 安装最新版 nodejs
使用最新版本, 当前是 16.x 的版本. 这里我使用了 LTS 版本. curl -fsSL https://deb.nodesource.com/setup_current.x | sudo -E ...
- redis-04配置文件
1.daemonize no # By default Redis does not run as a daemon. Use 'yes' if youneed it.# Note that Redi ...
- JAVA虚拟机16-方法的动态调用
更详细:https://www.cnblogs.com/jthr/p/15762527.html 1.子类重写父类方法 1.1父类 public class Father { public int n ...
- 和头条Jim博士的对话
鉴于他在头条里有拉黑人和删除不同意见评论的习惯,在我的文里贴上自己对他微头条的一些回复吧: 没想到Jim哥威力如此巨大,竟然令司马南粉丝来信倾诉"这下好了,全国人觉得爱国的人都不是什么好人& ...
- Solon2 之基础:一、常用应用配置说明
约定参考: //资源路径约定(不用配置:也不能配置) resources/app.yml( 或 app.properties ) #为应用配置文件 resources/WEB-INF/static/ ...
- MySQL数据类型补充
数据类型 整数数据类型 特殊说明: 对于整数类型,MySQL还支持在类型名称后面加小括号(M),而小括号中的M表示显示宽度,M的取值范围是(0, 255).int(M)这个M在字段的属性中指定了u ...