ASP.NET Core中HTTP管道和中间件的二三事
本文出自《从零开始学ASP.NET CORE MVC》
推荐文章:中间件是什么?在.NET Core中的工作原理又是怎样的呢?
配置ASP.NET Core请求(Request)处理管道
在本视频中,我们将讨论使用中间件组件为asp.net core 应用程序配置请求处理管道。
作为应用程序启动的一部分,我们要在Configure()
方法中设置请求处理管道。
public class Startup{public void ConfigureServices(IServiceCollection services){ }
public void Configure(IApplicationBuilder app, IHostingEnvironment env){if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); }
app.Run(async (context) => { await context.Response.WriteAsync("Hello World!"); }); }
}
目前我们的代码中有2个中间件在管道中 :UseDeveloperExceptionPage()方法和Run()方法
UseDeveloperExceptionPage 中间件:顾名思义,如果存在异常并且环境是Development
,此中间件会被调用,显示开发异常页面。 我们将在后面的视频中讨论这个DeveloperExceptionPage中间件和环境变量的使用。
第二个中间件是注册Run()
方法到管道中,它只能处理将一个信息传入Response
对象。 目前,它是一个响应每个请求的中间件,返回Hello world。
在这种情况下,无论您的请求路径是什么。 所有请求都会被这个中间件所处理,我们得到的返回值都是这个中间件调用Response
对象,返回的string类型的字符串。
返回的值是纯文本而不是html。 我们可以通过检查页面源代码来确认这一点。
可以看到,我们在源代码中没有任何html标记。 只是纯文本。
即使您现在创建一个为52abp.html
的文件,并且您在请求中包含该文件的路径,我们的应用程序也无法返回该静态文件。 这是因为,目前我们的请求处理管道没有可以提供静态文件的中间件,如html文件,图像,CSS和JavaScript文件
。
在后面的课程中,我们将添加所需的中间件以便能够提供静态文件。
研究下 Configure()方法中的代码。
app.Run(async (context) =>{await context.Response.WriteAsync("Hello World!");});
代码说明:
我们调用Run() 方法添加中间件到请求处理管道中。
如果将鼠标悬停在Run()方法上,则可以从 智能提示中看到
Run()
方法是作为IApplicationBuilder
接口的扩展方法实现的。这就是我们能够在IApplicationBuilder
对象应用程序上调用此Run()
方法的原因。我们传递给
Run()
方法的参数是一个RequestDelegate
,我们可以从智能提示中看到它。RequestDelegate
是一个作为HttpContext
对象的参数委托。通过这个
HttpContext
对象,中间件可以访问传入的http请求和传出的http响应。目前,我们使用
lambda
将请求,它通过委托内联的方式作为匿名方法传递,所以很多人都说lambda表达式是一种特殊的委托。如果你听不明白lambda表达式,委托,及内联,你可以参考学习:委托(delegate)
Lambda简介 ,或者等我录制C#的基础视频吧。
使用
Run()
扩展方法,我们只能将一个终端中间件
添加到请求管道。终端中间件
是我们之前已经说到过,他会使管道短路,不会去调用下一个中间件。
研究下面的代码
app.Run(async (context) =>{await context.Response.WriteAsync("从第一个中间件中打印Hello World");});
app.Run(async (context) =>{await context.Response.WriteAsync("从第二个中间件中打印Hello World");});
我们使用
Run()
方法注册了2个中间件。运行此项目时,我们只看到第一个中间件的响应,有返回值。
我们没有看到第二个中间件的响应。
这是因为,使用
Run()
方法注册的中间件无法调用管道中的下一个中间件。因此,我们使用
Run()
方法注册的中间件是终端中间件
如果您希望中间件能够调用管道中的下一个中间件,则使用Use()
方法注册中间件,如下所示。
app.Use(async (context, next) =>{await context.Response.WriteAsync("从第一个中间件中打印Hello World");await next();});
app.Run(async (context) =>{await context.Response.WriteAsync("从第二个中间件中打印Hello World");});
注意,Use()
方法有2个参数。第一个参数是HttpContext
上下文对象,第二个参数是Func
类型,即它是代表管道中下一个中间件的通用委托。
我们再看看以下代码
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILogger<Startup> logger){ app.Use(async (context, next) => { logger.LogInformation("MW1:传入请求");await next(); logger.LogInformation("MW1:传出响应"); });
app.Use(async (context, next) => { logger.LogInformation("MW2: 传入请求");await next(); logger.LogInformation("MW2: 传出响应"); });
app.Run(async (context) => {await context.Response.WriteAsync("MW3: 处理请求并生成响应"); logger.LogInformation("MW3: 处理请求并生成响应"); });}
ILogger < Startup >
被注入到Configure()
方法中Main()
方法调用的CreateDefaultBuilder()
配置日志记录您可以通过查看在GitHub的源代码验证这一点
:https://github.com/aspnet/MetaPackages/blob/release/2.2/src/Microsoft.AspNetCore/WebHost.cs检查方法
ConfigureLogging()
,* 您会发现,ILogger配置了Console,Debug和EventSource
三种.我们使用
依赖注入
的方式将ILogger
记录到系统中。如果使用.NET Core CLI运行项目,则可以在“控制台”窗口中查看记录的信息
如果直接从
Visual Studio
运行项目,则可以在输出窗口中
查看记录的信息。从输出窗口的下拉列表中选择ASP.NET Core Web Server。您将看到,信息按以下顺序记录
MW1:传入请求
MW2:传入请求
MW3:处理请求并生成响应
MW2:传出响应
MW1:传出响应
现在将上面的输出与微软的官方文档中的下图集合起来,是不是就清晰明了啊。吐槽下,微软的文档有粗糙。
image.png
请记住,asp.net Core中的中间件可以访问传入请求和传出响应
请求先到达
Middleware1
,它记录(MW1:传入请求),因此我们首先看到此消息。然后
Middleware1
调用next()
。next()
会调用管道中的Middleware2
。Middleware2
记录(MW2:传入请求)。然后
Middleware2
会调用next()
再调用Middleware3
.Middleware3
处理请求并生成响应。因此,我们看到的下一条消息是(MW3:处理请求并生成响应)
此时管道开始逆转。
此时控制权将,交回到
Middleware2
,并将Middleware3
生成的响应传递给它。Middleware2
记录(MW2:传出响应),这是我们接下来看到的。最后,
Middleware2
将控制权交给Midleware1
。Middleware1
记录 (MW1: 传出响应), 这是我们最后看到的。
请求处理管道的中3个非常重要的知识点:
所有的
请求
都会在每个中间件组件调用next()方法
之前触发。请求
按照图中箭头的所示方向,依次穿过所有管道。当中间件处理请求并产生响应时,请求处理流程在管道中开始反向传递。
所有的
响应
都会在每个中间件组件调用next()方法
之前触发。响应
按照图中箭头的所示方向,依次穿过所有管道。
小结
乱码问题
context.Response.ContentType = "text/plain; charset=utf-8";
硬广专区
如果您觉得我的文章质量还不错,欢迎打赏,也可以订阅我的视频哦
未得到授权不得擅自转载本文内容,52abp.com保留版权
文字版目录: https://www.52abp.com/Wiki/mvc/latest/1.Intro
交流QQ群:952387474《微软MVP带你学ASP.NET CORE》
【收费】腾讯课堂: https://ke.qq.com/course/392589?tuin=2522cdf3
【免费】youtube视频专区:http://t.cn/Ei0F2EB
免费的更新慢,收费的更新快,仅此而已。就这样。
「好看」的人都【在看】↓↓↓
ASP.NET Core中HTTP管道和中间件的二三事相关推荐
- ASP.NET Core 中的管道机制
首先,很感谢在上篇文章 C# 管道式编程 中给我有小额捐助和点赞的朋友们,感谢你们的支持与肯定.希望我的每一次分享都能让彼此获得一些收获,当然如果我有些地方叙述的不正确或不当,还请不客气的指出.好了, ...
- 在ASP.NET Core中编写合格的中间件
这篇文章探讨了让不同的请求去使用不同的中间件,那么我们应该如何配置ASP.NET Core中间件?其实中间件只是在ASP.NET Core中处理Web请求的管道.所有ASP.NET Core应用程序至 ...
- ASP.NET Core 中的那些认证中间件及一些重要知识点
前言 在读这篇文章之间,建议先看一下我的 ASP.NET Core 之 Identity 入门系列(ASP.NET Core 之 Identity 入门(一),ASP.NET Core 之 Ident ...
- 如何在 ASP.NET Core 中使用 URL Rewriting 中间件
URL rewriting 是根据预先配置好的一组规则去修改 request url,值得注意的是:URL Rewriting 的重写功能和 url 重定向 是两个概念,本篇我们就来讨论下如何在 AS ...
- ASP.NET Core 中基于工厂的中间件激活
IMiddlewareFactory/IMiddleware 是中间件激活的扩展点. UseMiddleware 扩展方法检查中间件的已注册类型是否实现 IMiddleware. 如果是,则使用在容器 ...
- 如何在 ASP.NET Core 中 自定义中间件
ASP.NET Core 是一个跨平台,开源的,轻量级,高性能 并且高度模块化的web框架,同时扩展性也是非常强,你可以在 request -> response 请求管道中安插各种中间件来根据 ...
- 理解ASP.NET Core中的中间件
中间件是ASP.NET Core的一个重要特点,ASP.NET Core应用程序之所以能够灵活地处理各种各样的请求,完成都是由于中间件,那么它究竟是怎么一回事呢? 一.理解中间件 ASP.NET Co ...
- asp向不同的用户发送信息_ASP.NET Core 中的那些认证中间件及一些重要知识点
前言 在读这篇文章之间,建议先看一下我的 ASP.NET Core 之 Identity 入门系列(一,二,三)奠定一下基础. 有关于 Authentication 的知识太广,所以本篇介绍几个在 A ...
- ASP.NET Core中使用GraphQL - 第二章 中间件
前文:ASP.NET Core中使用GraphQL - 第一章 Hello World 中间件 如果你熟悉ASP.NET Core的中间件,你可能会注意到之前的博客中我们已经使用了一个中间件, 这个中 ...
最新文章
- spring MVC cors跨域实现源码解析
- 【数论】排列组合学习笔记
- java float 转double_将float转换为double而不会丢失精度
- 在linux设置Mysql允许用户远程登录和限制用户远程登录
- altera fpga sdi输出方案_FPGA在电力电子中的应用有哪些?
- ubuntu服务器网站备份,用 Ubuntu 建立 Time Machine 备份服务器
- java解析xml乱码_大神们,我用DOM4j解析xml文档时,中文乱码
- eclipse中git分支创建与合并(-)
- 强化学习Q-learning简单理解
- 卡尔曼滤波原理及matlab仿真
- 15个网站失效死链接检查工具
- 用Python实现从Oracle到GreenPlum的表结构转换
- java有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。
- 最新的QQ跳转支付宝并自动领红包脚本。
- Python零基础速成班-第3讲-Python基础(中),list数组、tuple元组、dict字典、set集合
- PCA主成分分析 提取主成分,过滤噪音
- 扫描文档SDK ocr识别技术
- 利用QT加C++语言如何计算MACD指标,并请给出示例代码
- libtool的知识
- 【区块链论文整理】VLDB篇