飙血推荐
  • HTML教程
  • MySQL教程
  • JavaScript基础教程
  • php入门教程
  • JavaScript正则表达式运用
  • Excel函数教程
  • UEditor使用文档
  • AngularJS教程
  • ThinkPHP5.0教程

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

时间:2021-12-23  作者:cool-net  

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

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

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

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

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

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

微软给的图示:

image

域名 Core服务

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

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

internal class Program
{
    static void Main(string[] args)
    {
        new WebHostBuilder()
            .UseKestrel()
            .UseStartup<Startup2>()
            .Build()
            .Start();

        域名Line();
    }
}
public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
    }
}

image

这也是.Net Core的优点之一,提供一个平台,我们去选择我们需要的模块,摒弃那些多余的功能。优点是优点,一般开发中直接一把梭。

Kestrel 托管默认监听端口:5000

管道中间件

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

  1. Use
  2. Map
  3. Run

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

域名

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

public void Configure(IApplicationBuilder app)
{
	域名(async (context, next) =>
	{
		域名eLine("middleware1");
         await 域名ke();
	});
    域名(async (context, next) =>
	{
		域名eLine("middleware2");
	});
}

域名hen

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

域名hen(context =>
	 // 判断请求路径的开头是否是/h
	域名.StartsWithSegments(new PathString("/h")),
	c => 域名(async (context, next) =>
	{
		域名eLine("middleware1");
		await 域名ke();
	})
);
域名(async (context, next) =>
{
	域名eLine("middleware2");
});

image

域名

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

域名("/h", _app =>
{
	域名(async (context, next) =>
	{
		域名eLine("hello world");
	});
});

域名hen

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

域名hen(context => { return 域名y["name"] == "tony"; }, _app => {
    域名(async (context, next) => {
        域名entType = "text/plain; charset=utf-8";
        await 域名eAsync("i 服了 you");
    });
});

域名

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

域名(async context =>
{
    await 域名eAsync("hello world");
});

UseMiddleware

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

域名iddleware<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)
	{
		域名eAsync($"my name is {_name}").Wait();
		return 域名t(context);
	}
}

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

public void Configure(IApplicationBuilder app)
{
	域名(async (context, next) =>
	{
		域名eLine("middleware1 : in");
		await 域名ke();
		域名eLine("middleware1 : out");
	});
	域名(async (context, next) =>
	{
		域名eLine("middleware2 : in");
		await 域名ke();
		域名eLine("middleware2 : out");
	});
	域名(async context =>
	{
		域名eLine("Hello World");
		await 域名eAsync("Hello World");
	});
}

image

image

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

如果哪个中间件决定不往下执行,那通道也就短路了,比如我们去掉 middleware2await 域名ke();

执行到 域名eLine("middleware2 : out"); 就短路了,此路不通,原路返回。

image

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

  • 1、谨慎使用管道短路

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

编辑于 2021-12-22 18:19

之前的标题一直是.Net Core基础篇,现在改成了域名 Core基础篇,因为.Net Core域名 Core不是一个概念,平台 - 框架,容易引起误解。类似之前的.NET Framework域名的关系。也是我个人的疏忽和映像流,理所当然的写成了.Net Core

image

在这里多谢两位老哥的提点:@隆德尔@那一剑风情,评论我就不放了,要脸。

其他有理解错的地方,也希望大家能提点一二,写博客的目的就是在分享中不断纠错不断进步。

标签:编程
湘ICP备14001474号-3  投诉建议:234161800@qq.com   部分内容来源于网络,如有侵权,请联系删除。