【问题标题】:Read docker-compose environment variable from ASP.NET Core controller从 ASP.NET Core 控制器读取 docker-compose 环境变量
【发布时间】:2021-09-30 23:57:27
【问题描述】:

我正在尝试对 ASP.NET Core 5 Web API 项目进行 docker 化,因此我将把所有配置从 appSettings.json 转移到 docker-compose 环境部分。然后从控制器的环境部分读取它们。这个应该怎么做?

我曾尝试在控制器中使用IConfigurationEnvironment,但我刚刚得到Null

我的Program.cs 是:

namespace Order.Api
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
    }
}

StartUp.cs 是:

namespace Order.Api
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<OrderContext>(options =>
                options.UseSqlServer(Configuration.GetValue<string>("ConnectionString")));
                // options.UseSqlServer(Configuration.GetConnectionString("ConnectionString")));
            
            services.AddControllers();
            services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo {Title = "Order.Api", Version = "v1"}); });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseSwagger();
                app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Order.Api v1"));
            }

            app.UseHttpsRedirection();
            app.UseRouting();
            app.UseAuthorization();
            app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
        }
    }
}

docker-compose.override 是:

version: '3.4'

services:

  Order.Api :
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://0.0.0.0:80
      - ConnectionString=${ESHOP_AZURE_ORDERING_DB:-Server=sqldata;Database=Order;User Id=sa;Password=Pass@word}
      - MyConfig=Active
    ports:
      - "5001:80"


  sqldata :
    environment:
      - SA_PASSWORD=Pass@word
      - ACCEPT_EULA=Y
    ports:
      - "5433:1433"
    volumes:
      - order-sqldata:/var/opt/mssql



volumes:
  order-sqldata:
    external: false

【问题讨论】:

  • ASP.NET 自动从 env vars 读取配置,您只需为其提供正确的名称,请提供更多问题的详细信息,例如您的 docker-compose(或 docker 命令)和 appsettings.json
  • @ExplodingKitten 我已经添加了 docker-compose.override 文件并准备在控制器中读取 ConnectionString 或 MyConfig

标签: asp.net docker asp.net-core docker-compose environment-variables


【解决方案1】:

ASP.NET Core 提供从不同位置加载配置的能力:

  • appsettings.json
  • appsetting.&lt;EnvName&gt;.json
  • 环境变量
  • 用户机密
  • 命令行参数

您不必担心设置的来源。从开发人员的角度来看也是如此。你可以把它想象成一堆层(每个下一层都会覆盖上一层的设置)。例如。当您的应用程序启动时,它会尝试默认从 appsettings.json 加载设置,然后通过来自 appsetting.&lt;EnvName&gt;.json 的设置覆盖它,然后从环境变量等中覆盖它。

因此,当您尝试在环境变量中覆盖ConnectionString 时,首先需要检查appsettings.json。那里是如何定义的?让我们创建最简单的配置:

{
  "ConnectionStrings": {
    "ConnectionString": "from config"
  },
  "MyConfig": {
    "Key": "from config"
  }
}

要在Startup.cs 中读取此连接,您无需进行任何更改。使用您的options.UseSqlServer(Configuration.GetConnectionString("ConnectionString")));

要在环境变量中覆盖它,您需要为其提供特定名称:ConnectionStrings__ConnectionString=&lt;new_connection&gt;。这很简单,您需要将 JSON 配置展平,并使用__(双下划线)作为分隔符。

对于自定义配置(如MyConfig),您需要做更多的事情。您需要创建选项类,例如:

public class MyConfigOption
{
    public string Key { get; set; }
}

并在Startup.cs进行配置:

services.Configure<MyConfigOption>(Configuration.GetSection("MyConfig"));

然后您将能够在环境变量MyConfig__Key=value 中覆盖它。

要在你的控制器中使用它,你需要向 DI 询问这个选项:

public Controller(IOptions<MyConfigOption> options)
{
    this.options = options;
}

options 将包含您的配置。

更多详情请见Docs

【讨论】:

    猜你喜欢
    • 2020-07-16
    • 2021-08-15
    • 1970-01-01
    • 2015-06-17
    • 1970-01-01
    • 2023-01-30
    • 1970-01-01
    • 2021-06-12
    • 1970-01-01
    相关资源
    最近更新 更多