zoukankan      html  css  js  c++  java
  • asp.net core 系列之中间件基础篇(middleware)

    中间件是一种插入到管道上进行处理请求和响应的软件;每个中间件组件具有下面的功能:

    1. 选择是否把请求传递到管道上的下一个组件
    2. 可以在下一个组件的之前和之后做处理工作

    请求委托(request delegate)是用于建立(build)请求管道的,请求委托可以处理每个Http的请求;

    请求委托被配置的方法有三种:Run、Map、Use 扩展方法;

    用 IApplicationBuilder 创建中间件管道

    请求管道由一系列请求委托组成,一个调用一个;如下图

    每个委托都可以在下一个委托之前和之后执行。异常处理的委托在管道中被尽早调用,因为它可以捕获到后面管道中发生的错误。

    单个的请求委托可以使用 run

    使用一个匿名函数处理每个 Http 请求;并且使用的是 run ,它表示管道的结束,即最后一个中间件,不会再传递到下一个中间件

    public class Startup
    {
        public void Configure(IApplicationBuilder app)
        {
            app.Run(async context =>
            {
                await context.Response.WriteAsync("Hello, World!");
            });
        }
    }

    链式的多个请求委托在一起,使用 use

    next 参数 代表管道中的下一个委托,可以在下一个委托之前和之后进行处理;你也可以不调用 next 参数,直接短路管道(即不会传递到下一个委托/中间件)。

    public class Startup
    {
        public void Configure(IApplicationBuilder app)
        {
            app.Use(async (context, next) =>
            {
                // Do work that doesn't write to the Response.
                await next.Invoke();
                // Do logging or other work that doesn't write to the Response.
            });
    
            app.Run(async context =>
            {
                await context.Response.WriteAsync("Hello from 2nd delegate.");
            });
        }
    }

    顺序

    这里的顺序是指中间件被加到 Startup.Configure 方法的顺序决定了中间件顺序处理请求和逆序处理响应。所以,添加顺序是很重要的

    一般的应用中的 Startup.Configure 方法添加中间组件的顺序:

    1. Exception/error handling
    2. HTTP Strict Transport Security Protocol
    3. HTTPS redirection
    4. Static file server
    5. Cookie policy enforcement
    6. Authentication
    7. Session
    8. MVC
    public void Configure(IApplicationBuilder app)
    {
        if (env.IsDevelopment())
        {
            // When the app runs in the Development environment:
            //   Use the Developer Exception Page to report app runtime errors.
            //   Use the Database Error Page to report database runtime errors.
         // 添加异常中间件之后,后面中间件发生的异常都会被捕获
    app.UseDeveloperExceptionPage(); app.UseDatabaseErrorPage(); } else { // When the app doesn't run in the Development environment: // Enable the Exception Handler Middleware to catch exceptions // thrown in the following middlewares. // Use the HTTP Strict Transport Security Protocol (HSTS) // Middleware. app.UseExceptionHandler("/Error"); app.UseHsts(); } // Use HTTPS Redirection Middleware to redirect HTTP requests to HTTPS.使用https重定向中间件来重定向http请求到https请求 app.UseHttpsRedirection(); // Return static files and end the pipeline. app.UseStaticFiles(); // Use Cookie Policy Middleware to conform to EU General Data // Protection Regulation (GDPR) regulations. app.UseCookiePolicy(); // Authenticate before the user accesses secure resources. app.UseAuthentication(); // If the app uses session state, call Session Middleware after Cookie // Policy Middleware and before MVC Middleware. app.UseSession(); // Add MVC to the request pipeline. app.UseMvc(); }

    Use , Run 和 Map 的用法

    使用 Use , Run 和 Map 配置 HTTP 管道。

    Use 方法如果不调用next 就会造成短路;

    一些中间件组件可能会暴露 Run [ Middleware ] 方法 在管道的结束处运行;

    Map 扩展 主要用作一种分支管道的惯例:

      Map* 根据这给出的请求路径是否匹配来进入管道。

    public class Startup
    {
        private static void HandleMapTest1(IApplicationBuilder app)
        {
            app.Run(async context =>
            {
                await context.Response.WriteAsync("Map Test 1");
            });
        }
    
        private static void HandleMapTest2(IApplicationBuilder app)
        {
            app.Run(async context =>
            {
                await context.Response.WriteAsync("Map Test 2");
            });
        }
    
        public void Configure(IApplicationBuilder app)
        {
            app.Map("/map1", HandleMapTest1);
    
            app.Map("/map2", HandleMapTest2);
    
            app.Run(async context =>
            {
                await context.Response.WriteAsync("Hello from non-Map delegate. <p>");
            });
        }
    }

    如果路径匹配 /map1 ,则执行 HandleMapTest1;

    如果路径匹配 /map2 , 则执行 HandleMapTest2 ;

    如下示例:

    MapWhen 的用法

    当满足某个条件时,执行

    public class Startup
    {
        private static void HandleBranch(IApplicationBuilder app)
        {
            app.Run(async context =>
            {
                var branchVer = context.Request.Query["branch"];
                await context.Response.WriteAsync($"Branch used = {branchVer}");
            });
        }
    
        public void Configure(IApplicationBuilder app)
        {
            app.MapWhen(context => context.Request.Query.ContainsKey("branch"),
                                   HandleBranch);
    
            app.Run(async context =>
            {
                await context.Response.WriteAsync("Hello from non-Map delegate. <p>");
            });
        }
    }

    示例如下:

     

     另外,map支持嵌套

    app.Map("/level1", level1App => {
        level1App.Map("/level2a", level2AApp => {
            // "/level1/level2a" processing
        });
        level1App.Map("/level2b", level2BApp => {
            // "/level1/level2b" processing
        });
    });

    而且,map支持每次匹配多个段

    public class Startup
    {
        private static void HandleMultiSeg(IApplicationBuilder app)
        {
            app.Run(async context =>
            {
                await context.Response.WriteAsync("Map multiple segments.");
            });
        }
    
        public void Configure(IApplicationBuilder app)
        {
            app.Map("/map1/seg1", HandleMultiSeg);  //此句示例
    
            app.Run(async context =>
            {
                await context.Response.WriteAsync("Hello from non-Map delegate.");
            });
        }
    }

     另外还有很多内置的中间件可供使用,可根据需要进行使用

    参考网址:

    https://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-2.2

  • 相关阅读:
    Appium+python自动化2-环境搭建(下)【转载】
    Appium+python自动化1-环境搭建(上)【转载】
    python+requests接口自动化完整项目设计源码【转载】
    python接口自动化10-token登录【转载】
    linux_samba服务搭建
    linux_nginx反向代理
    linux_Nginx优化
    linux_mysql安装
    linux_http协议
    linux_nginx_rewrite
  • 原文地址:https://www.cnblogs.com/Vincent-yuan/p/10771983.html
Copyright © 2011-2022 走看看