ASP.NET Core 中间件(一)

作为一个合格的搬砖程序员,小妹打开了VS2019搭建了人生中的第一个.NetCore项目,根据IDE工具的提示搭建好项目后,在初始项目中我们会发现有这么几个文件
在这里插入图片描述
内部文件简介:
Properties&launchSettings.json 是一个启动配置文件,其用于应用的启动准备工作,包括环境变量,开发端口等。
在这里插入图片描述
Program类是项目的启动项,会为我们创建并初始化Web应用,并通过Startup类中的ConfigureServices和Configure方法,完成依赖注入和中间件管道的搭建。
在这里插入图片描述
Startup类
在这里插入图片描述
看到这,小妹有点懵了,啥是中间件?怎么配置中间件?额…带着问题找答案。百度了一下:

啥是中间件(Middleware)?
1.中间件是组装到应用程序管道中以处理请求和响应的软件。
2.每个组件选择是否将请求传递给管道中的下一个组件。
3.每个组件可以在调用管道中的下一个组件之前和之后执行工作。
4.请求委托(Request delegates)用于构建请求管道,处理每个HTTP请求。

怎么配置中间件?
请求委托使用Run,Map和Use扩展方法进行配置。单独的请求委托可以以内联匿名方法(称为内联中间件)指定,或者可以在可重用的类中定义它。这些可重用的类和内联匿名方法是中间件或中间件组件。请求流程中的每个中间件组件都负责调用流水线中的下一个组件,如果适当,则负责链接短路。
将HTTP模块迁移到中间件解释了ASP.NET Core和以前版本(ASP.NET)中的请求管道之间的区别,并提供了更多的中间件示例。

使用 IApplicationBuilder 创建中间件管道
ASP.NET Core请求流程由一系列请求委托组成,如下图所示(执行流程遵循黑色箭头):
在这里插入图片描述
每个委托可以在下一个委托之前和之后执行操作。委托还可以决定不将请求传递给下一个委托,这称为请求管道的短路。短路通常是可取的,因为它避免了不必要的工作。例如,静态文件中间件可以返回一个静态文件的请求,并使管道的其余部分短路。需要在管道早期调用异常处理委托,因此它们可以捕获后面管道的异常。
最简单的可能是ASP.NET Core应用程序建立一个请求的委托,处理所有的请求。此案例不包含实际的请求管道。相反,针对每个HTTP请求都调用一个匿名方法。
在这里插入图片描述
直接上代码吧!
在这里插入图片描述
上面文章说道中间件是应用程序管道中以处理请求和响应的软件,主要用委托实现,请求委托使用Run,Map和Use扩展方法进行配置
一、app.Run

   public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {

            app.Run(async context =>
            {
                await context.Response.WriteAsync("I'm Run1\r\n");
            });
            app.Run(async context =>
            {
                await context.Response.WriteAsync("I'm Run2\r\n");
            });
        }

运行IIS发现只运行了第一个中间件
在这里插入图片描述

说明确实在第一个app.Run终止了管道
结论:Run方法是一个约定, 并且一些中间件组件可能暴露在管道末端运行的或者不执行下一个中间件时可以使用Run [Middleware]方法

二、app.Use

  public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            
            app.Use(async (context, next) =>
            {
                await context.Response.WriteAsync("I'm Use1\r\n");
            });
            app.Run(async context =>
            {
                await context.Response.WriteAsync("I'm Run2\r\n");
            });
        }

运行结果,怎么肥事??不是说Use是内联中间件吗?为啥没有运行下一个中间件的方法??
在这里插入图片描述

仔细看以上的代码段,Use方法比Run方法多了一个参数next,next参数表示管道中的下一个委托,没有调用next.Invoke();尾端的Middleware即Run方法内没有执行。我们再修改代码。

 public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            
            app.Use(async (context, next) =>
            {
                await context.Response.WriteAsync("I'm Use1\r\n");
                await next.Invoke();
            });
            app.Run(async context =>
            {
                await context.Response.WriteAsync("I'm Run2\r\n");
            });
        }

运行结果:执行了两个委托
在这里插入图片描述
总结:使用Use方法,而没有调用next.Invoke(),Use的效果与Run的效果是一致的。调用next.Invoke()后Use与Run代码段都被执行了。需要注意的是,管道中可以增加多个middleware(中间件),他们是按顺序执行的,执行的顺序与在Configure方法中代码的顺序是一致的。
三、Map和MapWhen
Map比较不同,它将Middleware(中间件)添加到管道中,它是在管道中增加了分支。通过影射路径的方式,增加管道分支。我们保留上面例子,并增加代码。如下:

 public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            
            app.Use(async (context, next) =>
            {
                await context.Response.WriteAsync("I'm Use1\r\n");
                await next.Invoke();
            });

            app.Map("/maptest", MapTest);//映射路径访问指定的Middleware

            app.Run(async context =>
            {
                await context.Response.WriteAsync("I'm Run2\r\n");
            });
        }

        private static void MapTest(IApplicationBuilder app) {
            app.Use(async (context,next)=> {
                await context.Response.WriteAsync("this is maptest \r\n");
                await next.Invoke();
            });
        }

启动iis,在地址后面增加映射的地址如:https://localhost:44301/maptest,运行结果:
在这里插入图片描述
maptest分支被执行了

MapWhen:顾名思义满足条件的情况下执行相应的方法

 public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            
            app.Use(async (context, next) =>
            {
                await context.Response.WriteAsync("I'm Use1\r\n");
                await next.Invoke();
            });

            //app.Map("/maptest", MapTest);//映射路径访问指定的Middleware
            //如果有URL中的参数包含了zz,满足这个条件,就执行MapTest
            app.MapWhen(context=> { return context.Request.Query.ContainsKey("zz"); }, MapTest);
            app.Run(async context =>
            {
                await context.Response.WriteAsync("I'm Run2\r\n");
            });
        }

        private static void MapTest(IApplicationBuilder app) {
            app.Use(async (context,next)=> {
                await context.Response.WriteAsync("this is maptest \r\n");
                await next.Invoke();
            });
        }

如果有URL中的参数包含了zz,满足这个条件,就执行MapTest,地址:https://localhost:44301/?zz=1,运行结果:
在这里插入图片描述
通过以上的操作,小妹好像已经了解了什么是管道,什么是中间件,ASP.NET Core提供了附带中间件组件,如下:

中间件描述
Authentication提供身份验证支持
CORS配置跨域资源共享
Response Caching提供缓存响应支持
Response Compression提供响应压缩支持
Session提供用户会话管理
Static Files为静态文件和目录浏览提供服务提供支持
URL Rewriting Middleware用于重写 Url,并将请求重定向的支持

好了,有啥总结的不好的,请各位大神多多指教。回家!
.Net技术交流群:274407988,欢迎大家进群交流学习。

  • 11
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值