asp.net core 系列之中间件基础篇(middleware)
中间件是一种插入到管道上进行处理请求和响应的软件;每个中间件组件具有下面的功能:
- 选择是否把请求传递到管道上的下一个组件
- 可以在下一个组件的之前和之后做处理工作
请求委托(request delegate)是用于建立(build)请求管道的,请求委托可以处理每个Http的请求;
请求委托被配置的方法有三种:Run、Map、Use 扩展方法;
用 IApplicationBuilder 创建中间件管道
请求管道由一系列请求委托组成,一个调用一个;如下图
每个委托都可以在下一个委托之前和之后执行。异常处理的委托在管道中被尽早调用,因为它可以捕获到后面管道中发生的错误。
单个的请求委托可以使用 run
使用一个匿名函数处理每个 Http 请求;并且使用的是 run ,它表示管道的结束,即最后一个中间件,不会再传递到下一个中间件
public class Startup
{
public void Configure(IApplicationBuilder app)
{
app.Run(async context =>
{
await context.Response.WriteAsync("Hello, World!");
});
}
}
链式的多个请求委托在一起,使用 use
next 参数 代表管道中的下一个委托,可以在下一个委托之前和之后进行处理;你也可以不调用 next 参数,直接短路管道(即不会传递到下一个委托/中间件)。
public class Startup
{
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.");
});
}
}
顺序
这里的顺序是指中间件被加到 Startup.Configure 方法的顺序决定了中间件顺序处理请求和逆序处理响应。所以,添加顺序是很重要的
一般的应用中的 Startup.Configure 方法添加中间组件的顺序:
- Exception/error handling
- HTTP Strict Transport Security Protocol
- HTTPS redirection
- Static file server
- Cookie policy enforcement
- Authentication
- Session
- MVC
public void Configure(IApplicationBuilder app)
{
if (env.IsDevelopment())
{
// When the app runs in the Development environment:
// Use the Developer Exception Page to report app runtime errors.
// Use the Database Error Page to report database runtime errors.
// 添加异常中间件之后,后面中间件发生的异常都会被捕获
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
// When the app doesn't run in the Development environment:
// Enable the Exception Handler Middleware to catch exceptions
// thrown in the following middlewares.
// Use the HTTP Strict Transport Security Protocol (HSTS)
// Middleware.
app.UseExceptionHandler("/Error");
app.UseHsts();
} // Use HTTPS Redirection Middleware to redirect HTTP requests to HTTPS.使用https重定向中间件来重定向http请求到https请求
app.UseHttpsRedirection(); // Return static files and end the pipeline.
app.UseStaticFiles(); // Use Cookie Policy Middleware to conform to EU General Data
// Protection Regulation (GDPR) regulations.
app.UseCookiePolicy(); // Authenticate before the user accesses secure resources.
app.UseAuthentication(); // If the app uses session state, call Session Middleware after Cookie
// Policy Middleware and before MVC Middleware.
app.UseSession(); // Add MVC to the request pipeline.
app.UseMvc();
}
Use , Run 和 Map 的用法
使用 Use , Run 和 Map 配置 HTTP 管道。
Use 方法如果不调用next 就会造成短路;
一些中间件组件可能会暴露 Run [ Middleware ] 方法 在管道的结束处运行;
Map 扩展 主要用作一种分支管道的惯例:
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. <p>");
});
}
}
如果路径匹配 /map1 ,则执行 HandleMapTest1;
如果路径匹配 /map2 , 则执行 HandleMapTest2 ;
如下示例:
MapWhen 的用法
当满足某个条件时,执行
public class Startup
{
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)
{
app.MapWhen(context => context.Request.Query.ContainsKey("branch"),
HandleBranch); app.Run(async context =>
{
await context.Response.WriteAsync("Hello from non-Map delegate. <p>");
});
}
}
示例如下:
另外,map支持嵌套
app.Map("/level1", level1App => {
level1App.Map("/level2a", level2AApp => {
// "/level1/level2a" processing
});
level1App.Map("/level2b", level2BApp => {
// "/level1/level2b" processing
});
});
而且,map支持每次匹配多个段
public class Startup
{
private static void HandleMultiSeg(IApplicationBuilder app)
{
app.Run(async context =>
{
await context.Response.WriteAsync("Map multiple segments.");
});
} public void Configure(IApplicationBuilder app)
{
app.Map("/map1/seg1", HandleMultiSeg); //此句示例 app.Run(async context =>
{
await context.Response.WriteAsync("Hello from non-Map delegate.");
});
}
}
另外还有很多内置的中间件可供使用,可根据需要进行使用
参考网址:
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-2.2
asp.net core 系列之中间件基础篇(middleware)的更多相关文章
- asp.net core 系列之中间件进阶篇-编写自定义中间件(middleware)
中间件是被用到管道(pipeline)上来处理请求(request)和响应的(response). asp.net core 本身提供了一些内置的中间件,但是有一些场景,你可能会需要写一些自定义的中间 ...
- ASP.NET Core系列:中间件
1. 概述 ASP.NET Core中的中间件是嵌入到应用管道中用于处理请求和响应的一段代码. 2. 使用 IApplicationBuilder 创建中间件管道 2.1 匿名函数 使用Run, Ma ...
- asp.net core 系列 15 中间件
一.概述 中间件(也叫中间件组件)是一种装配到应用管道以处理请求和响应的软件. 每个组件:(1)选择是否将请求传递到管道中的下一个组件;(2)可以在管道中的下一个组件之前和之后执行工作. 请求委托用于 ...
- 探索ASP.NET MVC5系列之~~~1.基础篇---必须知道的小技能
其实任何资料里面的任何知识点都无所谓,都是不重要的,重要的是学习方法,自行摸索的过程 汇总:http://www.cnblogs.com/dunitian/p/4822808.html#mvc 本章D ...
- 【目录】asp.net core系列篇
随笔分类 - asp.net core系列篇 asp.net core系列 68 Filter管道过滤器 摘要: 一.概述 本篇详细了解一下asp.net core filters,filter叫&q ...
- asp.net core 系列 16 Web主机 IWebHostBuilder
一.概述 在asp.net core中,Host主机负责应用程序启动和生存期管理.host主机包括Web 主机(IWebHostBuilder)和通用主机(IHostBuilder).Web 主机是适 ...
- 技术的正宗与野路子 c#, AOP动态代理实现动态权限控制(一) 探索基于.NET下实现一句话木马之asmx篇 asp.net core 系列 9 环境(Development、Staging 、Production)
黄衫女子的武功似乎与周芷若乃是一路,飘忽灵动,变幻无方,但举手抬足之间却是正而不邪,如说周芷若形似鬼魅,那黄衫女子便是态拟神仙. 这段描写出自<倚天屠龙记>第三十八回. “九阴神抓”本是& ...
- Asp.net Core 系列之--4.事务、日志及错误处理
ChuanGoing 2019-11-17 这篇原本时想把事务处理.日志处理.错误处理.授权于鉴权一并介绍完的,授权和鉴权我想结合自定义权限来介绍,全部放到这里篇幅可能太长,因此权限部分将会在下篇来介 ...
- Asp.net Core 系列之--5.认证、授权与自定义权限的实现
ChuanGoing 2019-11-24 asp.net core系列已经来到了第五篇,通过之前的基础介绍,我们了解了事件订阅/发布的eventbus整个流程,初探dapper ORM实现,并且简单 ...
随机推荐
- MySQL常见备份方案
MySQL常见备份方案有以下三种: mysqldump + binlog lvm + binlog xtrabackup 本例为方便演示,数据库里面数据为空.下面开始动手 mkdir /opt/bac ...
- C# 插入、删除Excel分页符
引言 对Excel表格设置分页对我们预览.打印文档时是很方便的,特别是一些包含很多复杂数据的.不规则的表格,为保证打印时每一页的排版美观性或者数据的前后连接的完整性,此时的分页符就发挥了极大的作用.因 ...
- PowerDesigner如何将设计的表更新到数据库中
前言: 软件开发的过程中,将设计的表更新到数据库中是一件繁琐的事情,使用好工具,能够事半功倍. 环境介绍:Oracle 11g x64 前期准备: 1.PowerDesigner工具(本人是32位的) ...
- 计算机组装:台式机更换CPU
前言: 由于想在一台WindowsXP操作系统的台式机上使用虚拟机,但是这个台式机原装的CPU(Intel 奔腾 E2200)不支持虚拟化,所以我找了一颗支持虚拟化的CPU(Intel 酷睿 E850 ...
- 在Windows下同时安装Python2.x和Python3.x
前言: Python现在是两个版本共存,Python2.x和Python3.x都同时在更新.但是Python2.x和Python3.x的区别还是很多的(以后我可能会写一篇文章列举一下Python2.x ...
- Node.js使用supervisor遭遇‘supervisor’不是内部或外部命令,如果解决?
如果你有 PHP 开发经验,会习惯在修改 PHP 脚本后直接刷新浏览器以观察结果,而你 在开发 Node.js 实现的 HTTP 应用时会发现,无论你修改了代码的哪一部份,都必须终止 Node.js ...
- javascript知识详解之8张思维导图
学习的道路就是要不断的总结归纳,好记性不如烂笔头,so,下面将po出8张javascript相关的思维导图. 思维导图小tips:思维导图又叫心智图,是表达发射性思维的有效的图形思维工具 ,它简单却又 ...
- loj6045 「雅礼集训 2017 Day8」价
我们考虑最小割. 我一开始觉得是裸的最小割,就直接S到每个减肥药连up+p[i]的边,减肥药到药材连inf边,药材到T连up,然后得到了40分的好成绩. 之后我发现这是一个假的最小割,最小割割的是代价 ...
- 【最小生成树】Bzoj1601[Usaco2008 Oct]灌水
Description Farmer John已经决定把水灌到他的n(1<=n<=300)块农田,农田被数字1到n标记.把一块土地进行灌水有两种方法,从其他农田饮水,或者这块土地建造水库. ...
- 解决linux netcore https请求使用自签名证书忽略安全检查方法
当前系统环境:centos7 x64. dotnet 2.0. 不管是 ServicePointManager.ServerCertificateValidationCallback = (a, b, ...