


前言
ASP.NET Core的处理流程是一个管道,而中间件是装配到管道中的用于处理请求和响应的组件。中间件按照装配的先后顺序执行,并决定是否进入下一个组件。中间件管道的处理流程如下图(图片来源于官网):
管道式的处理方式,更加方便我们对程序进行扩展。
使用中间件
ASP.NET Core中间件模型是我们能够快捷的开发自己的中间件,完成对应用的扩展,我们先从一个简单的例子了解一下中间件的开发。
Run
首先,我们创建一个ASP.NET Core 应用,在Startup.cs中有如下代码:
- app.Run(async (context) =>
- {
- await context.Response.WriteAsync("Hello World!");
- });
这段代码中,使用Run方法运行一个委托,这就是最简单的中间件,它拦截了所有请求,返回一段文本作为响应。Run委托终止了管道的运行,因此也叫作终端中间件。
我们再看另外一个例子:
- app.Use(async (context, next) =>
- { //Do something here
-
- //Invoke next middleware
- await next.Invoke();
- //Do something here
- });
这段代码中,使用Use方法运行一个委托,我们可以在Next调用之前和之后分别执行自定义的代码,从而可以方便的进行日志记录等工作。这段代码中,使用next.Invoke()方法调用下一个中间件,从而将中间件管道连贯起来;如果不调用next.Invoke()方法,则会造成管道短路。
Map和MapWhen
处理上面两种方式,ASP.NET Core 还可以使用Map创建基于路径匹配的分支、使用MapWhen创建基于条件的分支。代码如下:
- private static void HandleMap(IApplicationBuilder app){
- app.Run(async context =>
- { await context.Response.WriteAsync("Handle Map");
- });
- }
- private static void HandleBranch(IApplicationBuilder app){
- app.Run(async context =>
- { var branchVer = context.Request.Query["branch"];
- await context.Response.WriteAsync($"Branch used = {branchVer}");
- });
- }
- public void Configure(IApplicationBuilder app, IHostingEnvironment env){
- app.Map("/map", HandleMap);
-
- app.MapWhen(context => context.Request.Query.ContainsKey("branch"),
- HandleBranch);
-
- app.Run(async context =>
- { await context.Response.WriteAsync("Hello World!");
- });
- }
上面的代码演示了如何使用Map和MapWhen创建基于路径和条件的分支。另外,Map方法还支持层级的分支,我们参照下面的代码:
- app.Map("/level1", level1App => {
- level1App.Map("/level2a", level2AApp => {
- // "/level1/level2a" processing
- });
- level1App.Map("/level2b", level2BApp => {
- // "/level1/level2b" processing
- });
- });
需要注意,使用 Map 时,将从 HttpRequest.Path 中删除匹配的Path,并针对每个请求将该线段追加到 HttpRequest.PathBase。例如对于路径
,当在level1App中进行处理时,它的请求路径被截断为
,当在level2AApp中进行处理时,它的路径就变成
了,而相应的PathBase会变为
。
原:ASP.NET Core 中间件基本用法 - 拓荒者-NET - 博客园 (cnblogs.com)