- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
在asp.net core中,中间件中间件是一种装配到应用管道以处理请求和响应的软件。 每个组件:
请求委托用于生成请求管道。 请求委托处理每个 HTTP 请求。 ASP.NET Core 请求管道包含一系列请求委托,依次调用。每个委托均可在下一个委托前后执行操作。 应尽早在管道中调用异常处理委托,这样它们就能捕获在管道的后期阶段发生的异常。 如下图所示:
在asp.net core中已经内置了挺多的中间件,包括身份验证,授权等等,详细的可以看官方文档 内置中间件 列表。 接下来主要讲一下如何编写我们自己的中间件,在前面的文章中我们也用到了自己写的中间件,用的是最简单的app.Use的方式。 Use 扩展可以使用两个重载:
优先使用后面的重载,因为它省去了使用其他重载时所需的两个内部每请求分配.
app.Use(async (context, next) =>
{
// 下游中间件执行前
await next.Invoke(); //往下执行中间件
// 下游中间件执行后
});
上面写法就是一个最简单的没有任何操作的中间件。 在调用await next.Invoke()前我们写的操作就是在下游中间件执行之前做的事情,对应的,在之后写的操作则是在下游中间件响应后做的事情。 举个例子,当我们要在下游中间件执行之前,做一些参数的赋值,如我想在Headers中添加一个头部, 。
app.Use(async (context, next) =>
{
context.Request.Headers.Add("TestMiddlewareAdd", "Abc");
await next.Invoke();
});
在添加之后,下游就可以获取Headers中TestMiddlewareAdd的值。 我们来实操一下,创建一个WebApi项目,然后在Program中MapControllers()之前添加上述中间件。 可以看到,Headers中已经加上了我们之前加的内容。 对应的,如果写在await next.Invoke()后面,则是不生效的,这个可以自行测试。那么在await next.Invoke()后面我们可以做一些什么操作呢?比如记录请求响应完成后的内容,或对相应内容做进一步的处理等等,根据我们的实际需要去写.
除了app.Use(),在asp.net core中还有几种中间件的编写方式.
app.Map();
app.MpaWhen();
app.Run();
app.UseMiddleware();
Map扩展用作约定来创建管道分支。 Map 基于给定请求路径的匹配项来创建请求管道分支。 如果请求路径以给定路径开头,则执行分支。 MapWhen基于给定谓词的结果创建请求管道分支。 Func<HttpContext, bool> 类型的任何谓词均可用于将请求映射到管道的新分支。 Run 委托不会收到 next 参数。 第一个 Run 委托始终为终端,用于终止管道。 Run 是一种约定。 某些中间件组件可能会公开在管道末尾运行的 Run[Middleware] 方法:
UseMiddleware是我们最常用的封装中间件的方式,中间件类是基于约定编写的。其约定如下:
构造函数和 Invoke/InvokeAsync 的其他参数由依赖关系注入 (DI) 填充.
接下来我们来实操基于约定编写一个Middleware类 。
public class AMiddleware
{
private readonly RequestDelegate _next;
public AMiddleware(RequestDelegate next)
=> _next = next;
public async Task InvokeAsync(HttpContext context, ILogger<AMiddleware> logger)
{
logger.LogInformation("AMiddleware Invoke");
await _next(context);
}
}
在Program使用UseMiddleware把中间件加入管道 。
app.UseAuthorization();
app.Use(async (context, next) =>
{
context.Request.Headers.Add("TestMiddlewareAdd", "Abc");
await next.Invoke();
});
app.UseMiddleware<AMiddleware>();
app.MapControllers();
app.Run();
启动项目发出请求。可以看到下图结果: 需要注意的是,这里的Middleware会自动注册为一个单例,所以在构造器注入时,无法注入Scope生命周期的服务。 如果注入,启动会直接报错 。
public class AMiddleware
{
private readonly RequestDelegate _next;
private readonly TestMiddlewareDi _testMiddlewareDi;
public AMiddleware(RequestDelegate next, TestMiddlewareDi testMiddlewareDi)
{
_next = next;
_testMiddlewareDi = testMiddlewareDi;
}
public async Task InvokeAsync(HttpContext context, ILogger<AMiddleware> logger)
{
logger.LogInformation("AMiddleware Invoke");
logger.LogInformation($"AMiddleware _testMiddlewareDi: {_testMiddlewareDi.Id}");
await _next(context);
}
}
builder.Services.AddScoped<TestMiddlewareDi>();
当我们需要注入Scope生命周期的服务时,直接在InvokeAsync方法中添加注入.
public class AMiddleware
{
private readonly RequestDelegate _next;
public AMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context, ILogger<AMiddleware> logger, TestMiddlewareDi testMiddleware)
{
logger.LogInformation("AMiddleware Invoke");
logger.LogInformation($"AMiddleware _testMiddlewareDi: {testMiddleware.Id}");
await _next(context);
}
}
运行结果可以看到,正常运行,并且每次请求Id都是不一样的.
除了基于约定实现中间件,asp.net core还有一个基于工厂的中间件激活扩展。 IMiddlewareFactory/IMiddleware 是中间件激活的扩展点,具有以下优势:
UseMiddleware 扩展方法检查中间件的已注册类型是否实现 IMiddleware。 如果是,则使用在容器中注册的 IMiddlewareFactory 实例来解析 IMiddleware 实现,而不使用基于约定的中间件激活逻辑。 中间件在应用的服务容器中注册为作用域或瞬态服务。 接下来我们来实现一个IMiddleware 。
public class FactoryMiddleware : IMiddleware
{
private readonly ILogger _logger;
private readonly TestMiddlewareDi _testMiddleware;
public FactoryMiddleware(ILogger<FactoryMiddleware> logger, TestMiddlewareDi testMiddleware)
{
_logger = logger;
_testMiddleware = testMiddleware;
}
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
_logger.LogInformation("FactoryMiddleware Invoke");
_logger.LogInformation($"FactoryMiddleware _testMiddlewareDi: {_testMiddleware.Id}");
await next(context);
}
}
app.UseAuthorization();
app.Use(async (context, next) =>
{
context.Request.Headers.Add("TestMiddlewareAdd", "Abc");
await next.Invoke();
});
app.UseMiddleware<AMiddleware>();
app.UseMiddleware<FactoryMiddleware>();
app.MapControllers();
app.Run();
需要注意的是,这种方式必须把中间件注册到依赖注入容器中,否则会出现以下错误: 注册注入之后,我们再次启动服务,并测试请求.
builder.Services.AddScoped<FactoryMiddleware>();
一切顺利执行.
基于约定的中间件无法通过构造函数注入Scope生命周期的服务,只能通过Invoke方法的参数进行注入。 基于工厂的中间件只能通过构造函数添加注入,Invoke无法注入(因为是基于IMiddleware接口的实现).
基于约定的中间件无需手动注册进依赖注入容器。 基于工厂的中间件必须注册进依赖注入容器,且生命周期注册为作用域或瞬态服务.
基于约定的中间件生命周期为单例 基于工厂的中间件生命周期为作用域 。
中间既然是一种管道的模式,那么必然和顺序有关系,管道前面的中间件先执行,后面的中间件后执行。 那么这个顺序会带来哪种影响呢? 这里盗官方文档图,下图显示了 ASP.NET Core MVC 和 Razor Pages 应用的完整请求处理管道。 这里UseCors 和 UseStaticFiles 顺序是最容易看出影响的。 若是UseStaticFiles在UseCors之前调用,则检索静态文件时,不会检查是否跨站点调用。所有静态文件可以直接检索。 若是相反,则在跨站检索静态文件时,则会优先检查站点是否跨域,若是跨域则无法检索静态文件.
由此我们可以想到,当我们需要做一些前置校验的中间件时,可以把中间件顺序放在前面,校验不通过直接终止后续请求,可以提高应用的响应效率.
欢迎进群催更.
最后此篇关于asp.netcore之中间件的文章就讲到这里了,如果你想了解更多关于asp.netcore之中间件的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
有人可以给我一个更简单的以下代码的解决方案(它正在展开给定结构 0xFC :: len :: payload :: ... :: 0x0A :: 0x0D 的整数列表): object Payload
我已经在我的网站上安装了 SSL 证书,但 intermediate.crt 无法正常工作。任何 SSL 检查器(例如 GeoTrust Checker)都告诉我,缺少中间 key 。网站上已经使用了
如何让图像从这个框的中间开始? (中间纵横) 最佳答案 有几种方法可以做到这一点,如果它需要在所有浏览器(IE7+ 和其他浏览器)中工作,你需要做不同的事情来让它在某些情况下工作。 使用绝对位置
如何强制 min-height 和 vertical-align:middle 为 td 元素或其内部元素工作? 最佳答案 td 元素上的 height 等同于 min-height,因为如果需要,表
我正在尝试自动滚动到订单簿的中间行。 我有 orderBook div,其中放置了带有 orderBook 的表。该表的其中一行有一个 id middleRow。我想做的是滚动该行并将其放置在 ord
我正在尝试在 javascript 中计算绝对定位元素的 transform-origin 属性,以便它们在悬停时填充整个视口(viewport)。 我尝试通过 x 除以窗口宽度和 y 除以窗口高度来
我有休闲字符串 ' this is my string ' 是否可以删除开头和结尾的所有空格,只在单词之间留一个空格。 要选择我使用过的所有空间: SELECT regexp_replace('
我正在设法创建我的第一个复杂的 J2E 解决方案,并且在每个教程中我都发现了某种中间表的用法,如下所示: 表:用户、用户角色、角色虽然逻辑会简单地向用户表添加一个键来引用它在角色表上的角色,但为什么要
我正在寻找以下解决方案。我想定位一个图像元素,例如 在中间。所以高度是视口(viewport)的高度,宽度会自动设置,图像的中间应该在视口(viewport)宽度的中间。 我搜索的一个例子就像下面的网
我正在设计一种布局,它更像是注册用户的个人仪表板。我让它变得简单,使用基本的 2 列网格,一个用于侧边栏,一个用于主要内容。 因为,例如,80% 的网站使用将发生在一个单独的子系统中,在无 chrom
我有三个不同的 div 标签(不在彼此内部)和代码,所以它有一个把单词放在左边、中间或右边,但中心非常偏离中心。这是 HTML 代码: .desc { float: right; color:
我有以下CSS http://jsbin.com/azivip/75/edit我想让黄色的 div 高度填充蓝色和绿色 div 之间的空间。使用高度继承似乎使 div 超出了绿色 div。 有什么想法
我不得不在其父元素的中间放置一些文本。我用下面的代码实现了它: #div1 { position: relative; margin: 0; padding: 0; } #div2 {
发现一个使用合法证书(由thawte 签名)的网站,但所有浏览器都会拒绝它。我不明白为什么。thawte 的支持告诉我一个域有两个证书,然后将这个 https://www.sslshopper[dot
我正在尝试使用 OpenSSL 创建证书链,但出于某种原因,当我在我的计算机上安装我的根 CA 并尝试验证证书链时,它总是告诉我它找不到证书的颁发者.为了让事情发生,我必须安装中间 CA,这是没有意义
我看到 REST 的一大好处是依赖 HTTP 缓存。我不是在争论这个,而是完全认同这个想法。但是,我从来没有看到对中间 HTTP 缓存的更深入的解释。 如果我将 Cache-control heade
查看此图片 Facebook Messenger Android App Buttons ( MESSENGER\ACTIVE ) 我怎样才能做到这一点? 详细信息:- 带有 2px 红色边框的 di
我的任务是制作漂亮的文本,在文本中间加一条白线,如下图所示。是否可以使用 css 来实现?这是 Fiddle .container{ height:200px; width:400px;
在拉丁文字中,字母有大写和小写形式。在 Python 中,如果你想比较两个字符串而不考虑它们的大小写,你可以使用 'string'.upper() 或 'string'.lower() 将它们转换为相
我正在使用 awk 对文件进行一些文本处理。例如删除尾随空格。 awk '{gsub(/ +$/, "")} {print $0}' filename 这很好用。但是当我将输出重定向到原始文件时。它变
我是一名优秀的程序员,十分优秀!