首页 > 编程语言 >.NET ASP.NET CORE 中间件 管道

.NET ASP.NET CORE 中间件 管道

时间:2023-08-28 10:57:49浏览次数:37  
标签:CORE 委托 app 中间件 next 管道 context NET

一、管道

路由、认证、会话、缓存等等,他们都是通过管道来实现的ASP.NET Core 应用一般都是使用某个框架来开发,MVC、Web API,建立在某个特殊的中间件之上。通过编写中间件,扩展请求管道,在ASP.NET Core上创建我们自己的WEB框架,API网关Ocelot,API网关框架。
Middleware两个职责:1、选择是否将请求传递给管道中的下一个中间件2、在管道中的下一个中间件的前后执行工作。
每个中间件都有权作出决定是否将请求传递给下一个中间件,也可以直接作出响应,管道的短路。
短路就是指不再将请求继续往下传递,而是结束请求并开始响应。
短路时非常有必要  

二、运用原理

1、app.RunRun相当于一个终结点,Run之后的中间件不会被执行,因为它不像Use一样可以调用next.Invoke();
            //接收一个委托  参数:http上下文对象  这个委托就是中间件
            //Adds a terminal middleware delegate to the application's request pipeline
            //向应用程序的请求管道添加终端中间件委托 (添加是一个终端(终结点)中间件)
            app.Run(async context =>
            {
                await context.Response.WriteAsync("Hello Run");
            });

2、app.Use传入的委托中含有一个委托参数,我们一般用next来接收这个委托参数,通过调用next.Invode()方法来调用下一个中间件,这样Use之后的中间件才能够被执行
            //Adds a terminal middleware delegate to the application's request pipeline
            //next 指向下一个中间件
            app.Use(async (context, next) =>
            {
                // 请求处理
                await context.Response.WriteAsync("Middleware 1 Begin");
                await next();
                // 响应 (返回的时候)
                await context.Response.WriteAsync("Middleware 1 End");
            });

3、app.Map只有访问特定的路径才会执行
            app.Map("/map", app =>
            {
                app.Run(context =>
                {
                    Console.WriteLine("map-run");
                    return Task.FromResult("run done");
                });
            });


3、所谓的中间件,其实就是一堆委托
4、
            //注册自定义中间件 
            app.UseMiddleware<>(自定义的中间件类);

5、中间件的顺序,管道里的中间是有顺序的。就是我们代码的顺序顺序是很重要
6、
            // 内置一个依赖注入框架,添加内置中间件

            // 这个中间件,他依赖一些服务类,是通过依赖注入注入进来
            // 跨域中间件 需要先注册服务 在ConfigureServices services.AddCors();
            app.UseCors();
中间件所依赖的类,都可以通过服务容器注入
7、路由中间件
            // 终端路由中间件
            //mvc 核心中间件 路由中间件
            // 识别路由,匹配路由和终结点
            // 通用的
            app.UseRouting();

            //UseEndpoints 向中间件管道添加终结点执行。 它会运行与所选终结点关联的委托。
            // 终结点中间件
            // 终结点 ,可以视为应用程序提供针对HTTP请求的处理器
            // MVC应用,终结点就对应着控制器中的某个方法
            // WebAPI 
            // 可配置的
            app.UseEndpoints(endpoints =>
            {
                //mvc 核心中间件
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });

8、自定义中间件!
    // 按照约定来创建
    // 具有类型为RequestDelegate的参数的公共构造函数
    // 名为Invoke或者InvokeAsync的公共方法,这个方法必须满足两个条件:返回Task;接受类型HttpContext的第一个参数;
    public class MarkdownMiddleware
    {
        private readonly RequestDelegate next;
        private readonly IWebHostEnvironment hostEn;
        public MarkdownMiddleware(RequestDelegate next, IWebHostEnvironment hostEnv)
        {
            this.next = next;
            this.hostEn = hostEnv;
        }

        public async Task InvokeAsync(HttpContext context)
        {
            string path = context.Request.Path.ToString();
            //只处理.md文件请求
            if (!path.EndsWith(".md", true, null))
            {
                await next.Invoke(context);
                return;
            }
            //是否存在文件流
            var file = hostEn.WebRootFileProvider.GetFileInfo(path);
            if (!file.Exists)
            {
                await next.Invoke(context);
                return;
            }

            //ude.netstandard  检测流的编码
            using var stream = file.CreateReadStream();
            Ude.CharsetDetector cdet = new Ude.CharsetDetector();
            cdet.Feed(stream);
            cdet.DataEnd();
            //探测文本编码类型
            string charset = cdet.Charset ?? "UTF-8";
            //复位,因为CharsetDetector已经把stream的指针往后挪了
            //因为后面要重新读这个流
            stream.Position = 0;
            using StreamReader reader = new StreamReader(stream, Encoding.GetEncoding(charset));

            //读取md问题
            string mdTest = await reader.ReadToEndAsync();

            Markdown md = new Markdown();
            //md-》html
            string html = md.Transform(mdTest);
            context.Request.ContentType = "test/hem;charset=UTF-8";
            await context.Response.WriteAsync(html);
        }
    }
使用 在 Startup.cs 中 Configure 添加
            //中间件 md转换器 
            app.UseMiddleware<MarkdownMiddleware>();
9、扩展方法创建一个类扩展
    public static class CostomMiddlewareExtensions
    {
        //扩展方法
        public static IApplicationBuilder UseTest(this IApplicationBuilder app)
        {
            return app.UseMiddleware<MarkdownMiddleware>();
        }
    }
使用
            app.UseTest();
10、你编写WEB应用,实际就是再写中间件。。全都是中间件。。你写的控制器,也是中间件里的一部分。整个ASP.NET Core应用,都是在管道里运行的管道里放的都是中间件
11、源码https://github.com/dotnet/aspnetcoreUse  实际是通过委托将 _components 集合添加(有两个USE,每个USE 都是在_components 列表里,把委托添加到进去,别的啥也没有干没有关系,两个独立的Func委托,现在还不是真正中间件)Build  构造管道方法   方法中:先加一个默认(底层)中间件 为了报错     管道就是这两句话构成的、      挨个执行Func委托,然后把前一个中间件,塞到后一个委托中,这样遍历执行      中间件委托就形成了一条链子,责任链模式<设计模式>:流程化      组成了一个责任链      最后一个被执行的,是第一个中间件,把第一个中间件返回出去了      当我们请求进来的时候,由主机创建HTTP上下文对象,然后把上下文对象赛到第一个中间件
      这里是倒叙遍历
        for (var c = _components.Count - 1; c >= 0; c--)
        {
            app = _components[c](app);
        }
     (底层)中间件传个2号中间件的委托,包含有链子的中间件就被创建出来,把2号中间件返回出来    1号->2号->底层->2号->1号







标签:CORE,委托,app,中间件,next,管道,context,NET
From: https://www.cnblogs.com/buzheng11/p/17661691.html

相关文章

  • Kubernetes 对接 GlusterFS 磁盘扩容实战
    前言知识点定级:入门级使用HeketiTopology扩容磁盘使用HeketiCLI扩容磁盘实战服务器配置(架构1:1复刻小规模生产环境,配置略有不同)主机名IPCPU内存系统盘数据盘用途ks-master-0192.168.9.912450100KubeSphere/k8s-masterks-master-1192.1......
  • .NET 实现Azure DevOps中通过API对工作项的ID列表获取
    前言:最近在做对接AzureDevOps的API的工作,最开始也做了很多调研,官方给的API也是很丰富与完整,但是在对接工作项(WorkItems)时发现,官方并没有给WorkItems的列表或者分页的API,具体原因并不清楚,不过也可以通过id的list去获取工作项的list,id的list就需要通过wiql去获取。这里对A......
  • 20230628 java.net.URLDecoder
    介绍java.net.URLDecoderpublicclassURLDecoderURL解码器对应的URL编码器类是URLEncoderURL编码模式保留字符A到Z、a到z、0到9,以及.-~_用+字符替换所有的空格将其他所有字符编码为UTF-8,并将每个字节都编码为%后面紧跟一个两位的十六进制数......
  • 20230628 java.net.URLEncoder
    介绍java.net.URLEncoderpublicclassURLEncoderURL编码器对应的URL解码器类是URLDecoderURL编码模式保留字符A到Z、a到z、0到9,以及.-~_用+字符替换所有的空格将其他所有字符编码为UTF-8,并将每个字节都编码为%后面紧跟一个两位的十六进制数......
  • Netty源码学习3——Channel ,ChannelHandler,ChannelPipeline
    系列文章目录和关于我零丶引入在Netty源码学习2——NioEventLoop的执行中,我们学习了NioEventLoop是如何进行事件循环以及如何修复NIO空轮询的bug的,但是没有深入了解IO事件在netty中是如何被处理的,下面我们以服务端demo代码为例子,看下和IO事件处理密切的Channel如上在编写nett......
  • .NET|--.Net Core 6 |--Swagger显示注释信息
    1.输出xml文件选中API项目,鼠标右击,选中"属性",勾选"生成>>输出>>文档文件"修改Program.cs中配置//varbuilder=WebApplication.CreateBuilder(args);builder.Services.AddSwaggerGen(options=>{options.SwaggerDoc("v1",newO......
  • 解决:docker 443: connect: network is unreachable
    1、配置镜像加速器您可以通过修改daemon配置文件/etc/docker/daemon.json来使用加速器sudomkdir-p/etc/dockersudotee/etc/docker/daemon.json<<-'EOF'{"registry-mirrors":["https://liadaibh.mirror.aliyuncs.com"]}EOFsudosystemctldaemon-......
  • kubernetes 指标监控 metrics-server 的配置
    kubernetes指标监控metrics-server的配置 apiVersion:v1kind:ServiceAccountmetadata:labels:k8s-app:metrics-servername:metrics-servernamespace:kube-system---apiVersion:rbac.authorization.k8s.io/v1kind:ClusterRolemetadata:labels......
  • 开发模式:ASP.NET MVC4
    1)新建ASP.NETMVC4网站项目;2)引用前面的Data和Service工程项目;3)向网站项目添加install-packageautofac.mvc4install-packageautomapper-version4.1.14)新建ViewModels、Mappings两个文件夹;5)生成必要的ViewModels;6)向Mappings中复制文件:AutoMapperConfiguration.cs......
  • kubernetes client-go快速入门及源码阅读
    client-go是kubernetes官方维护的一个go语言客户端,用于与k8s集群交互,使用client-go可以很方便的完成k8s的二次开发(似乎也必不可少),无论是稳定性还是健壮性都有充分的保障。client-go代码版本:v0.20.2个人水平有些,一定会出现不严谨或者错误的地方,如有错误麻烦评论指正,谢谢版......