此文是在官方文档的基础上做的个人笔记,一些简单的内容就没用再列出来了,参考官方文档:https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/middleware/?view=aspnetcore-5.0
文章目录
中间件是一种装配到应用管道以处理请求和响应的组件,可以选择是否将请求传递到管道中的下一个组件而且也可以在管道的下一个组件前后执行工作。
使用app.Run
、app.Map
、app.Use
方法来配置请求委托。请求管道中的每个中间件负责调用管道中的下一个中间件或者使管道短路直接返回。当使管道短路时就被称为“终端中间件”,如静态文件中间件,当遇到静态文件时就直接返回。
1.使用IApplicationBuilder创建中间件
每一个管道的logic在下一个中间件执行前执行,more logic 则是在下一个中间件返回后执行。应该尽可能早的调用异常处理中间件,这样它就能捕获在管道的后期阶段发生的异常。
-
app.Use
委托:有一个 next参数,可以选择是否传递到下一个中间件。在服务端发送响应之后,不要调用next.Invoke
方法,否则会发生异常。 -
app.Run
委托:没有next参数。始终为终止委托,用来终止管道。所以如果你自己的中间件用来终止管道就命名为RunXXXX,否则命名为UseXXX。
public void Configure(IApplicationBuilder app)
{
app.Use(async (context, next) =>
{
// Do work that doesn't write to the Response.
await next.Invoke();
// Do logging or other work that doesn't write to the Response.
});
app.Run(async context =>
{
await context.Response.WriteAsync("Hello from 2nd delegate.");
});
}
-
app.Map
委托:用来对中间件管道进行分支,如果请求路径符合指定的开头,则执行分支
public class Startup
{
private static void HandleMapTest1(IApplicationBuilder app)
{
app.Run(async context =>
{
await context.Response.WriteAsync("Map Test 1");
});
}
private static void HandleMapTest2(IApplicationBuilder app)
{
app.Run(async context =>
{
await context.Response.WriteAsync("Map Test 2");
});
}
public void Configure(IApplicationBuilder app)
{
app.Map("/map1", HandleMapTest1);
app.Map("/map2", HandleMapTest2);
app.Run(async context =>
{
await context.Response.WriteAsync("Hello from non-Map delegate");
});
}
}
请求 | 响应 |
localhost:1234 | Hello from non-Map delegate. |
localhost:1234/map1 | Map Test 1 |
localhost:1234/map2 | Map Test 2 |
localhost:1234/map3 | Hello from non-Map delegate. |
-
app.MapWhen
:根据一个表达式确定是否要分支 -
app.UseWhen
:根据一个表达式确定是否要执行分支里的管道。与MapWhen
的区别是:UseWhen
分支管道里中间件执行完之后,会回到主管道继续执行主管道的中间件。
2.中间件执行顺序
下图时Core MVC和Razor Pages应用的完整请求处理管理,你可以了解以下顺序,然后决定你自己的中间件应该放在哪里。顺序对于安全性、性能和功能至关重要。
其中Endpoint对于MVC和Razor Pages来说具体如下:
3. 如何自定义中间件
参考这里