环境变量 > appsetting.json配置urls>默认地址" />

NetCore 启动地址配置详解 UseUrls("xxxx") > 环境变量 > appsetting.json配置urls>默认地址

您所在的位置:网站首页 py环境变量配置 NetCore 启动地址配置详解 UseUrls("xxxx") > 环境变量 > appsetting.json配置urls>默认地址

NetCore 启动地址配置详解 UseUrls("xxxx") > 环境变量 > appsetting.json配置urls>默认地址

2023-05-29 13:28| 来源: 网络整理| 查看: 265

背景

程序在发布部署时候,设置环境ASPNETCORE_URLS不生效,也没在代码里使用UseUrls("xxxx"),启动一直是http://localhost:5000.最后测试发现只有在appsettings.json中配置urls才生效,网上找了半天资料也没看到有什么问题。

最终翻看源代码,发现是在StartUp中的Configure替换了全局IConfiguration导致。

平时开发大体知道程序启动时候端口启用顺序是UseUrls("xxx")> 环境变量 > 默认,具体是怎么确定使用哪个配置的,没找到资料,所有才有了本文。

启动地址配置的几种方式介绍环境变量ASPNETCORE_URLS #windows  set ASPNETCORE_URLS=http://localhost:6000 #linux  export ASPNETCORE_URLS=http://localhost:60001.2.3.4.UseUrls("http://localhost:6000")appsettings.json新增urls或者server.urls配置 {     "urls":"http://localhost:6000;http://localhost:6001",     "server.urls":"http://localhost:6000;http://localhost:6001" }1.2.3.4.使用系统默认说明

程序启动过程中,一个配置key会重复使用,先放这里

//WebHostDefaults.ServerUrlsKey如下 public static readonly string ServerUrlsKey = "urls";1.2.Web项目启动地址配置说明

今天是介绍启动方式,所以web启动流程不是重点。直接进入正题。

Web启动最终是调用WebHost.StartAsync,源代码在这WebHost。其中有个方法EnsureServer来获取启动地址

private static readonly string DeprecatedServerUrlsKey = "server.urls";

//省略 var urls = _config[WebHostDefaults.ServerUrlsKey] ?? _config[DeprecatedServerUrlsKey];

1.2.3.4.

是从全局IConfigration实例中获取启动地址。所以我的遇到问题这里就解决了。但环境变量和UseUrls是如何解析并记载进来的呢?下面就开今天讲解。

环境变量配置详解

一般Web程序启动代码如下:

Host.CreateDefaultBuilder(args)    .ConfigureWebHostDefaults(webBuilder =>    {        webBuilder.UseStartup();    }).Build().Run();1.2.3.4.5.

其中ConfigureWebHostDefaults的会用调用扩展方法ConfigureWebHost

public static IHostBuilder ConfigureWebHostDefaults(this IHostBuilder builder, Actionconfigure)  {      return builder.ConfigureWebHost(webHostBuilder =>      {          WebHost.ConfigureWebDefaults(webHostBuilder);

         configure(webHostBuilder);      });  }

1.2.3.4.5.6.7.8.9.

以上代码都是定义在Microsoft.Extensions.Hosting中。

继续看ConfigureWebHost代码,这个方法就定义在Microsoft.AspNetCore.Hosting程序集中了。

public static IHostBuilder ConfigureWebHost(this IHostBuilder builder, Actionconfigure) {     //这里会加载环境变量     var webhostBuilder = new GenericWebHostBuilder(builder);     //这里会调用UseUrls等扩展方法     configure(webhostBuilder);     builder.ConfigureServices((context, services) => services.AddHostedService());     return builder; }1.2.3.4.5.6.7.8.9.

在GenericWebHostBuilder 构造函数里有如下代码,用来初始化配置,最终添加到全局IConfiguration实例中,也就是Host中IConfiguration实例。

builder.ConfigureServices((context, services) => services.AddHostedService

//加入环境变量配置 config = new ConfigurationBuilder()            .AddEnvironmentVariables(prefix: "ASPNETCORE")            .Build(); //把配置加载到Host _builder.ConfigureHostConfiguration(config => {     config.AddConfiguration(_config);

    // We do this super early but still late enough that we can process the configuration     // wired up by calls to UseSetting     ExecuteHostingStartups(); })

1.2.3.4.5.6.7.8.9.10.11.12.13.

AddEnvironmentVariables环境变量解析最终会使用EnvironmentVariablesConfigurationProvider,有兴趣的可以看下AddEnvironmentVariables源代码,EnvironmentVariablesConfigurationProvider解析环境的方法如下。

public override void Load() {     Load(Environment.GetEnvironmentVariables()); }

internal void Load(IDictionary envVariables) {     var data = new Dictionary(StringComparer.OrdinalIgnoreCase);     //这里是筛选ASPNETCORE_开头的环境变量     var filteredEnvVariables = envVariables         .Cast()         .SelectMany(AzureEnvToAppEnv)         .Where(entry => ((string)entry.Key).StartsWith(_prefix, StringComparison.OrdinalIgnoreCase));

    foreach (var envVariable in filteredEnvVariables)     {         //这里会把前缀去掉加到配置里         var key = ((string)envVariable.Key).Substring(_prefix.Length);         data[key] = (string)envVariable.Value;     }

    Data = data; }

1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.

IConfiguration中的key是不区分大小写的,所有最终的效是在全局IConfiguration中新增一条key为urls的记录。而如果使用默认Host.CreateDefaultBuilder(),appsettings.json中的配置会先加载。如果在appsettings.json中配置urls的话,环境变量也定义了,就会被环境变量的覆盖掉。

UseUrls解析

UseUrls解析最终会调用GenericWebHostBuilder中的UseSetting

//UseUrls代码如下 public static IWebHostBuilder UseUrls(this IWebHostBuilder hostBuilder, params string[] urls) {     if (urls == null)     {         throw new ArgumentNullException(nameof(urls));     }

    return hostBuilder.UseSetting(WebHostDefaults.ServerUrlsKey, string.Join(ServerUrlsSeparator, urls)); }

//GenericWebHostBuilder中的UseSetting public IWebHostBuilder UseSetting(string key, string value) {     _config[key] = value;     return this; }

1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.

由于这个方法是在 new GenericWebHostBuilder(builder);之后调用,就是 configure(webhostBuilder);,上面代码也有说明。所以IConfiguration中urls如果有值,又会被覆盖掉。所以优先级最高的是UseUrls()。

默认地址

假如以上3种配置都没有,就是地址为空,会使用默认策略。这里是源代码,下面是默认策略使用的地址

 ////// The endpoint Kestrel will bind to if nothing else is specified.  ///public static readonly string DefaultServerAddress = "http://localhost:5000";

 ////// The endpoint Kestrel will bind to if nothing else is specified and a default certificate is available.  ///public static readonly string DefaultServerHttpsAddress = "https://localhost:5001";

1.2.3.4.5.结论启动端口设置优先级如下:UseUrls("xxxx") > 环境变量 > appsetting.json配置urls>默认地址不要随意替换全局的IConfiguration,如果不手动加入环境变量解析的话,会丢失一部分配置数据。将自己的配置注入的全局,可以使用以下方式,这样就会把配置追加到全局的IConfiguration中  Host.CreateDefaultBuilder(args)      .ConfigureWebHostDefaults(builder =>      {          builder.UseStartup();      }).ConfigureAppConfiguration(config =>      {          config.AddJsonFile("config.json", true, true);      }).Build().Run();1.2.3.4.5.6.7.8.



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3