本文出自《从零开始学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管道和中间件的二三事相关推荐

  1. ASP.NET Core 中的管道机制

    首先,很感谢在上篇文章 C# 管道式编程 中给我有小额捐助和点赞的朋友们,感谢你们的支持与肯定.希望我的每一次分享都能让彼此获得一些收获,当然如果我有些地方叙述的不正确或不当,还请不客气的指出.好了, ...

  2. 在ASP.NET Core中编写合格的中间件

    这篇文章探讨了让不同的请求去使用不同的中间件,那么我们应该如何配置ASP.NET Core中间件?其实中间件只是在ASP.NET Core中处理Web请求的管道.所有ASP.NET Core应用程序至 ...

  3. ASP.NET Core 中的那些认证中间件及一些重要知识点

    前言 在读这篇文章之间,建议先看一下我的 ASP.NET Core 之 Identity 入门系列(ASP.NET Core 之 Identity 入门(一),ASP.NET Core 之 Ident ...

  4. 如何在 ASP.NET Core 中使用 URL Rewriting 中间件

    URL rewriting 是根据预先配置好的一组规则去修改 request url,值得注意的是:URL Rewriting 的重写功能和 url 重定向 是两个概念,本篇我们就来讨论下如何在 AS ...

  5. ASP.NET Core 中基于工厂的中间件激活

    IMiddlewareFactory/IMiddleware 是中间件激活的扩展点. UseMiddleware 扩展方法检查中间件的已注册类型是否实现 IMiddleware. 如果是,则使用在容器 ...

  6. 如何在 ASP.NET Core 中 自定义中间件

    ASP.NET Core 是一个跨平台,开源的,轻量级,高性能 并且高度模块化的web框架,同时扩展性也是非常强,你可以在 request -> response 请求管道中安插各种中间件来根据 ...

  7. 理解ASP.NET Core中的中间件

    中间件是ASP.NET Core的一个重要特点,ASP.NET Core应用程序之所以能够灵活地处理各种各样的请求,完成都是由于中间件,那么它究竟是怎么一回事呢? 一.理解中间件 ASP.NET Co ...

  8. asp向不同的用户发送信息_ASP.NET Core 中的那些认证中间件及一些重要知识点

    前言 在读这篇文章之间,建议先看一下我的 ASP.NET Core 之 Identity 入门系列(一,二,三)奠定一下基础. 有关于 Authentication 的知识太广,所以本篇介绍几个在 A ...

  9. ASP.NET Core中使用GraphQL - 第二章 中间件

    前文:ASP.NET Core中使用GraphQL - 第一章 Hello World 中间件 如果你熟悉ASP.NET Core的中间件,你可能会注意到之前的博客中我们已经使用了一个中间件, 这个中 ...

最新文章

  1. spring MVC cors跨域实现源码解析
  2. 【数论】排列组合学习笔记
  3. java float 转double_将float转换为double而不会丢失精度
  4. 在linux设置Mysql允许用户远程登录和限制用户远程登录
  5. altera fpga sdi输出方案_FPGA在电力电子中的应用有哪些?
  6. ubuntu服务器网站备份,用 Ubuntu 建立 Time Machine 备份服务器
  7. java解析xml乱码_大神们,我用DOM4j解析xml文档时,中文乱码
  8. eclipse中git分支创建与合并(-)
  9. 强化学习Q-learning简单理解
  10. 卡尔曼滤波原理及matlab仿真
  11. 15个网站失效死链接检查工具
  12. 用Python实现从Oracle到GreenPlum的表结构转换
  13. java有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。
  14. 最新的QQ跳转支付宝并自动领红包脚本。
  15. Python零基础速成班-第3讲-Python基础(中),list数组、tuple元组、dict字典、set集合
  16. PCA主成分分析 提取主成分,过滤噪音
  17. 扫描文档SDK ocr识别技术
  18. 利用QT加C++语言如何计算MACD指标,并请给出示例代码
  19. libtool的知识
  20. 【区块链论文整理】VLDB篇

热门文章

  1. disk genius_如何预约Apple Store商店或Genius Bar
  2. 2018-2019 20165226 Exp9 Web安全基础
  3. Vue CLI 3开发中屏蔽烦人的EsLint错误
  4. MATLAB编程与应用系列-关于MATLAB编程入门教程的总体编写安排
  5. 设置utf8编码问题
  6. SecureCRT 中 python 命令行使用退格键(backspace)出现 ^H 解决办法
  7. nginx源码学习Unix - Unix域协议
  8. linux部署的java应用,浏览器访问时,报域名解析错误
  9. 给IT新人的15个建议:苦逼程序员的辛酸反省与总结
  10. 入门基础-VC网络编程入门