ASP.NET Core 中间件

   日期:2020-11-05     浏览:90    评论:0    
核心提示:作为一个合格的搬砖程序员,小妹打开了VS2019搭建了人生中的第一个.NetCore项目,根据IDE工具的提示搭建好项目后,在初始项目中我们会发现有这么几个文件内部文件简介:Properties&launchSettings.json 是一个启动配置文件,其用于应用的启动准备工作,包括环境变量,开发端口等。Program类是项目的启动项,会为我们创建并初始化Web应用,并通过Startup类中的ConfigureServices和Configure方法,完成依赖注入和中间件管道的搭建。

作为一个合格的搬砖程序员,小妹打开了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,并将请求重定向的支持

好了,有啥总结的不好的,请各位大神多多指教。回家!

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服