zoukankan      html  css  js  c++  java
  • Asp.NetCore 自定义中间件

    这节演示一下自定义中间件,第一节我们讲到,中间件的处理流程就像一个俄罗斯套娃,那这种俄罗斯套娃型的流程内部是如何实现的呢,下面请看代码​。

        ​第一种写法是直接写在Configure方法中的,使用app.Use(委托)配合lambda表达式使用,适合很轻量级的中间件。​

    app.Use(async (context, next) =>
      {
          await context.Response.WriteAsync("CustomerMiddleWare1-in
    ");
          await next();
          await context.Response.WriteAsync("CustomerMiddleWare1-out");
      });

    ​微软约定中间件需要两个参数,一个是httpcontext上下文对象,一个是Task类型的委托​。通过上下文对象,处理请求,通过委托​传递上下文对象到下一个中间件(这也是套娃模式的由来)。

        ​这也限制了方法,必须是异步的async方法,调用next()之后,上下文对象发送给下一中间件了,该方法就会处于等待状态,直到后续的中间件处理完毕,返回后,再执行next()方法之后的代码​。(关于同步和异步的有关知识,将在后续进行讲解)

        ​除了使用Use()方法,还有一种用法,这个方法有点特殊,因为它不存在next()方法传递上下文对象,它是请求管道的底,用于直接返回响应

    //run 是终端中间件,他是没有next()方法的,只要进入这个中间件,后续的中间件都不会执行了,从它这里请求完毕原路返回 
     app.Run(async context =>
     {
          await context.Response.WriteAsync("I am End MiddleWare
    ");
     });

     ​.NetCore 3.x推出了一个新的中间件,叫EndPoints

    app.UseEndpoints(endpoints =>
     {
            endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
     });

      ​它跟Run()一样,是兜底的中间件,但是用法比较特殊了,微软给我们的默认配置就是直接路由到某一页面,一般是网站首页​。

     下面看一下运行结果的演示,有如下三个中间件:

     //use是添加中间中间件,就是处理完了,继续传给下一个中间件,它有next()委托
     app.Use(async (context, next) =>
     {
       await context.Response.WriteAsync("CustomerMiddleWare1-in
    ");
       await next();
       await context.Response.WriteAsync("CustomerMiddleWare1-out");
     });
     app.Use(async (context, next) =>
     {
       await context.Response.WriteAsync("CustomerMiddleWare2-in
    ");
       await next();
       await context.Response.WriteAsync("CustomerMiddleWare2-out
    ");
     });
    //run 是终端中间件,他是没有next()方法的,只要进入这个中间件,后续的中间件都不会执行了,从它这里请求完毕原路返回 
     app.Run(async context =>
     {
       await context.Response.WriteAsync("I am End MiddleWare
    ");
     });

    运行结果为:

      这很直观的反应了中间件的顺序执行,以及嵌套执行

     下面看一下如何定义一个真正的自定义中间件

        首先,我们要明确,微软规定的自定义中间件的要求

            1.具有类型为RequestDelegate参数的公共构造函数,这个参数就是请求委托,它在一个个的中间件中传递

             2.具有Invoke或者InvokeAsync的方法,该方法的返回值必须是Task,而且第一个参数必须是HttpContext

     public class MyMiddleWare
        {
            private readonly RequestDelegate _next;
    
            public MyMiddleWare( RequestDelegate next )
            {
                _next = next;
            }
    
            public async Task InvokeAsync(HttpContext context)
            {
                //此处写中间件业务逻辑
                //然后调用next指向下一个中间件
                //调用next之前,属于请求部分的处理
                await _next(context);
                //next执行完毕之后,属于相应部分的处理
            }
        }

       ​定义完成以后,使用UseMiddleware<中间件>()将自定义中间件添加进来

    app.UseMiddleware<MyMiddleWare>();

     ​但这样的用法,还是少了一点优雅与灵活性,我们可以通过扩展方法的形式,为IApplicationBuilder添加扩展方法,实现自定义中间件添加与配置的灵活应用(扩展方法在之前的文章中有讲)​

    public static class MyMiddleWareExtension
        {
            public static IApplicationBuilder UseMymiddleware(this IApplicationBuilder app)
            {
                return app.UseMiddleware<MyMiddleWare>();
            }
        }

    这样的话,就可以直接调用方法添加中间件了

     //使用扩展方法的形式,添加自定义中间件然后可以通过构造方法的形式,传递配置参数
     app.UseMymiddleware();

     初学者可对此做初步了解,对其中设计的代码语法知识,是必须要掌握的。另外,如果需要查看ASP.NetCore的源码,请访问https://github.com/dotnet/aspnetcore自行下载或克隆到本地

     这是我公众号二维码,最新的文章会同步至此

  • 相关阅读:
    bzoj3167 [Heoi2013]Sao
    51Nod1220 约数之和
    THUSC2017 游记
    基于线性代数的一般图匹配
    COGS2608 [河南省队2016]无根树
    CTSC2017 & APIO2017 游记
    cef GeneralUsage
    CefApp和CefClient的作用
    cef源码分析之cefsimple
    【chromium】cef是如何进行版本控制的?
  • 原文地址:https://www.cnblogs.com/charlesmvp/p/13279226.html
Copyright © 2011-2022 走看看