今天来讨论一个ASP.NET Core 很重要概念管道和中间件,在ASP.NET Core中,针对HTTP请求采用pipeline也就是通常说的管道方式来处理,而管道容器内可以挂载很多中间件(处理逻辑)“串联”来处理HTTP请求,每一个中间件都有权决定是否需要执行下一个中间件,或者直接做出响应。这样的机制使得HTTP请求能够很好的被层层处理和控制,并且层次清晰处理起来甚是方便。 示意图如下:

  ASP.NET Core - 中间件与管道(1)

  为了再次说明管道和中间件的概念,举一个官方给出的权限验证的例子,中间件A,B分别按顺序挂载在管道容器中,A为权限验证中间件,只有通过A的权限验证才能执行B,如果没有通过A的验证,A有权中断管道处理直接返回相应的错误提示例如401等。这样必须由上一节点来调用的串行递归执行方式就是pipeline,而每一个节点就是中间件或者叫中间组件。现在我们来看看如何在ASP.NET Core中使用中间件和管理自己的HTTP管道


 

  环境配置与Startup

  在了解中间件之前我们需要先知道Startup这个类具体运作方式,我们以下面这段代码为例:

    /// <summary>
    /// web宿主的入口类
    /// </summary>
    public class Startup
    {
        //加入服务项到容器, 这个方法将会被runtime调用
        public void ConfigureServices(IServiceCollection services)
        {

        }
        
        /// <summary>
        /// 配置HTTP请求管道
        /// </summary>
        /// <param name="app">被用于构建应用程序的请求管道 只可以在Startup中的Configure方法里使用</param>
        /// <param name="env">提供了访问应用程序属性,如环境变量</param>
        /// <param name="loggerFactory">提供了创建日志的机制</param>
        public void Configure(IApplicationBuilder app,IHostingEnvironment env,ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole(); 
            
            if (env.IsDevelopment()) //根据配置的环境为开发环境,则会配置抛出异常错误界面
            {
                app.UseDeveloperExceptionPage();  //抛出详细的异常错误界面
            }

            //管道断路
            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("Hello World!");
            });
        }
    }

  可以看到 Startup.cs 内有两个方法,一个是用来配置接口服务到管道容器中的ConfigureServices, 一个是用来配置管道中间件的Configure。

  为什么必须是这两个方法名?

  其实这两个方法名并不是规定死的,但也不是任意规定的,他是根据容器的环境变量来判断的,这里先给出官方文档《多环境下工作》

  我们可以在文档中了解到,Core使用“ASPNETCORE_ENVIRONMENT”字段来描述当前运行环境名称这就是上文中提到的环境配置,官方预设了3个环境名分别是Development(开发环境), Staging(测试环境), Production(生产环境),如果您使用的是VSCode您可以在.vscode文件夹下的launch.json中找到“ASPNETCORE_ENVIRONMENT”字段,可以发现默认情况下是Development,那说这些到底有什么用呢?

  ASP.NET Core - 中间件与管道(1)

  在Startup中规定,配置服务和中间件两个方法可以根据环境名称来命名和选择调用,命名规则为ConfigureServices{ENVIRONMENT}和Configure{ENVIRONMENT}。如 ASPNETCORE_ENVIRONMENT = “Development” 则ConfigureServices和Configure 可以写成ConfigureServicesDevelopment 和 ConfigureDevelopment ,其他也是如此。这样就可以通过配置ASPNETCORE_ENVIRONMENT 来决定该调用哪一个配置方法了。

  ConfigureServices和Configure是什么环境下的呢?

    ConfigureServices和Configure就好像Switch 语句中的 default一样的道理,如果没有找到任何符合环境名的方法名,就会执行调用这两个方法。如配置了Development,但却没有给出ConfigureServicesDevelopment ,这时就会执行ConfigureServices,如果都没有就会抛出异常。

  必须设置成预设环境名吗?

  环境名配置的参数名不必是预设值,你可以自己写一个,比如LogEnv等等。

  接下来我们看一下实现的代码:

     /// <summary>
    /// web宿主的入口类
    /// </summary>
    public class Startup
    {
        //加入服务项到容器, 这个方法将会被runtime调用
        public void ConfigureServices(IServiceCollection services)
        {

        }

        /// <summary>
        /// Log环境下配置HTTP请求管道
        /// </summary>
        /// <param name="app"></param>
        public void ConfigureLogHelp(IApplicationBuilder app){
            app.Run(async (context) =>
            {
                 await context.Response.WriteAsync("Hello World - ConfigureLogHelp");
            });
        }    

        /// <summary>
        /// 开发环境下配置HTTP请求管道
        /// </summary>
        /// <param name="app"></param>
        public void ConfigureDevelopment(IApplicationBuilder app){
            app.Run(async (context) =>
            {
                 await context.Response.WriteAsync("Hello World - ConfigureDevelopment");
            });
        }


            
        /// <summary>
        /// 默认情况下配置HTTP请求管道
        /// </summary>
        /// <param name="app">被用于构建应用程序的请求管道。只可以在 Startup 中的 Configure 方法里使用</param>
        /// <param name="env">提供了访问应用程序属性,如环境变量</param>
        /// <param name="loggerFactory">提供了创建日志的机制</param>
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {

            //管道断路
            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("Hello World!");
            });
        }
    
Startup.cs

相关文章:

  • 2018-09-06
  • 2020-06-08
  • 2021-01-04
  • 2019-01-24
  • 2022-01-16
  • 2018-03-27
  • 2019-03-29
猜你喜欢
  • 2021-12-22
  • 2019-07-25
  • 2021-01-14
  • 2019-05-22
  • 2018-09-18
  • 2021-04-26
  • 2021-02-14
  • 2018-07-20
相关资源
相似解决方案