欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ASP.NET CORE 请求处理管道

程序员文章站 2022-05-04 20:06:24
...

目录

前瞻:

收集中间件:

创建管道:


 

前瞻:

RequestDelegate 这个委托类型的参数是  HttpContext 类型的,大家都知道 得到了 HttpContext 的实例就可以 为所欲为 想返回啥就返回
ASP.NET CORE 请求处理管道

 

收集中间件:

(以下说的中间件其实就是委托, ASP.NET Core 默认的管道中间件只有一个 就是 404)

ASP.NET CORE 请求处理管道
如下  IApplicationBuilder 就是收集中间件的方法
ASP.NET CORE 请求处理管道

详情可以查看  IApplicationBuilder  Use 方法  每次调用 Use方法 就相当于 ICollection<T> 集合调用 Add()


ASP.NET CORE 请求处理管道

 

按照这个 格式的参数我们实现一个,首先把Configure 方法框架默认的东西先注释下 在 Configure 方法中我们啥都不要,

写下如下代码 下面每调用一次Use 就是添加一个管道中间件

 

ASP.NET CORE 请求处理管道

 

创建管道:

 

每次启动或者调制代码时都会在 IApplicationBuilder   的 Build 方法中执行如下逻辑,如下代码虽然简单但是 特别精髓

遍历反转以后的中间件列表 : 以下面 app 作为初始参数 也就是说 ,如果一个中间件也没添加,就会直接返回 404

现在在下边遍历反转以后的集合 ,得到结果就是 http 请求管道模型

(如下流程来自 ASP.NET CORE 源码)

ASP.NET CORE 请求处理管道

 

当我们注册了中间件后这里就有意思了 ,

之前的 Configure 方法 中使用 Use 方法 其实就是在往  ICollection<T>  _components  集合  中添加元素


 

ASP.NET CORE 请求处理管道

上面 foreach 的过程只做了一件事就是让 每个 中间件 知道自己的 next 是谁 (也可以叫闭包)

ASP.NET CORE 请求处理管道

遍历完成后就得到了 一个 : RequestDelegate  委托实例 ,也就是我们每次 http 请求都要走的 处理管道

ASP.NET CORE 请求处理管道

 

跑一下看看,谷歌浏览器得到一个空白页面,POSTMAN 得到了半截结果

看来是受 404 的影响了,那么最后注册的中间件不能再调用 next.Invoke(content)

ASP.NET CORE 请求处理管道

ASP.NET CORE 请求处理管道

注释掉 404 部分的逻辑 再试试看

ASP.NET CORE 请求处理管道

结果: 谷歌浏览器是乱码的 ,POSTMAN 是正常的

ASP.NET CORE 请求处理管道

ASP.NET CORE 请求处理管道

那就给 Response 对象设置一下 Content-Type了

提示: 设置 Content-type 一定要在 第一次 Write 响应 前 设置

不然浏览器拿不到结果 , POSTMAN 只能拿到 设置属性之前的部分结果,剩余的被截断

ASP.NET CORE 请求处理管道

查看结果:

ASP.NET CORE 请求处理管道

以下是涉及的 代码:

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.Use( next => {
                return new RequestDelegate(async content =>
                {
                    content.Response.ContentType = "text/html; charset=utf-8";
                    // 处理逻辑
                    await content.Response.WriteAsync("<h3>做点啥1 之前</h3> ");
                    // 交接控制权
                    await next.Invoke(content);
                    //处理逻辑
                    await content.Response.WriteAsync("<h3>做点啥1 之后</h3>  ");
                });
            });

            app.Use(next =>
            {
                return new RequestDelegate(async content =>
                {
                    await content.Response.WriteAsync("<h3>做点啥2</h3>  ");
                    await next.Invoke(content);
                    await content.Response.WriteAsync("<h3>做点啥2</h3>  ");
                });
            });

            app.Use(next =>
            {
                return new RequestDelegate(async content =>
                {
                    await content.Response.WriteAsync("<h3>做点啥3</h3>  ");
                    // await next.Invoke(content);
                    await content.Response.WriteAsync("<h3>做点啥3</h3>  ");
                });
            });
        }

最后再说  IApplicationBuilder 的一个拓展方法 Run() 终结式注册

功能和 Use  一样但是还是有点差别 ,不管用什么方式添加 ,最终都是要 foreach 遍历这些流程的

源码如下 : 

ASP.NET CORE 请求处理管道

试用: 这样子的方式添加中间件 就拿不到 next 了 ,这样看来 Run适合用来做最后一个 中间件的添加,天然的就接触不到 next 

ASP.NET CORE 请求处理管道

当然还有其他很多的添加中间件的扩展方法 ,我们自己也可以写,但是万变不离其宗,底层都是依靠 Use 方法往集合添加中间件,最后都是要 Foreach 遍历的

 

有什么不对的请指正

有用请点赞留言,谢谢

相关标签: ASP.NET .net