前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >asp.net core 系列之中间件基础篇(middleware)

asp.net core 系列之中间件基础篇(middleware)

作者头像
Vincent-yuan
发布2019-09-10 18:08:56
5530
发布2019-09-10 18:08:56
举报
文章被收录于专栏:Vincent-yuanVincent-yuan

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

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

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

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

用 IApplicationBuilder 创建中间件管道

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

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

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

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

代码语言:javascript
复制
public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.Run(async context =>
        {
            await context.Response.WriteAsync("Hello, World!");
        });
    }
}
链式的多个请求委托在一起,使用 use

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

代码语言:javascript
复制
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
代码语言:javascript
复制
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* 根据这给出的请求路径是否匹配来进入管道。

代码语言:javascript
复制
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 的用法

当满足某个条件时,执行

代码语言:javascript
复制
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支持嵌套

代码语言:javascript
复制
app.Map("/level1", level1App => {
    level1App.Map("/level2a", level2AApp => {
        // "/level1/level2a" processing
    });
    level1App.Map("/level2b", level2BApp => {
        // "/level1/level2b" processing
    });
});

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

代码语言:javascript
复制
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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-04-26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 用 IApplicationBuilder 创建中间件管道
    • 单个的请求委托可以使用 run
      • 链式的多个请求委托在一起,使用 use
      • 顺序
      • Use , Run 和 Map 的用法
      相关产品与服务
      消息队列 TDMQ
      消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档