background
When the program is released and deployed, set the environment ASPNETCORE_URLS does not take effect, and UseUrls("xxxx") is not used in the code. Startup is always http://localhost:5000. Finally, the test found that only in Appsettings The configuration of urls in JSON takes effect. I haven't seen any problems after looking for information on the Internet for a long time.
Finally, looking at the source code, it is found that the global IConfiguration is replaced by Configure in StartUp.
Usually, developers generally know the port enabling order when the program is started
Useurls ("XXX") > environment variables > default. Specifically, how to determine which configuration to use. No information is found, so this article is available.
Introduction to several ways of starting address configuration
- Environment variable ASPNETCORE_URLS
#windows set ASPNETCORE_URLS=http://localhost:6000 #linux export ASPNETCORE_URLS=http://localhost:6000
- UseUrls("http://localhost:6000")
- appsettings.json adds urls or server urls configuration
{ "urls":"http://localhost:6000;http://localhost:6001", "server.urls":"http://localhost:6000;http://localhost:6001" }
- Use system default
explain
During program startup, a configuration key will be reused and put here first
//WebHostDefaults.ServerUrlsKey is as follows public static readonly string ServerUrlsKey = "urls";
Description of Web project startup address configuration
Today's web startup mode is not the key point. Go straight to the point.
Web startup is ultimately a call to webhost Startasync, the source code is here WebHost . There is a method, EnsureServer, to get the startup address
private static readonly string DeprecatedServerUrlsKey = "server.urls"; //ellipsis var urls = _config[WebHostDefaults.ServerUrlsKey] ?? _config[DeprecatedServerUrlsKey];
Is to obtain the startup address from the global IConfigration instance. So I solved the problem here. But how are environment variables and UseUrls parsed and recorded? Let's talk about today.
Detailed explanation of environment variable configuration
The general Web program startup code is as follows:
Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }).Build().Run();
The of ConfigureWebHostDefaults will call the extension method ConfigureWebHost
public static IHostBuilder ConfigureWebHostDefaults(this IHostBuilder builder, Action<IWebHostBuilder> configure) { return builder.ConfigureWebHost(webHostBuilder => { WebHost.ConfigureWebDefaults(webHostBuilder); configure(webHostBuilder); }); }
The above codes are defined in Microsoft Extensions. Hosting.
Continue to look at the ConfigureWebHost code. This method is defined in Microsoft AspNetCore. Hosting assembly.
public static IHostBuilder ConfigureWebHost(this IHostBuilder builder, Action<IWebHostBuilder> configure) { //Environment variables will be loaded here var webhostBuilder = new GenericWebHostBuilder(builder); //Extension methods such as UseUrls will be called here configure(webhostBuilder); builder.ConfigureServices((context, services) => services.AddHostedService<GenericWebHostService>()); return builder; }
In the GenericWebHostBuilder constructor, the following code is used to initialize the configuration and finally add it to the global
IConfiguration instance, that is, IConfiguration instance in Host.
builder. ConfigureServices((context, services) => services. AddHostedService()); This is the focus of web startup. Those who are interested can have a look
//Add environment variable configuration _config = new ConfigurationBuilder() .AddEnvironmentVariables(prefix: "ASPNETCORE_") .Build(); //Load configuration into 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(); })
AddEnvironmentVariables the EnvironmentVariablesConfigurationProvider will eventually be used for environment variable resolution. If you are interested, please take a look at AddEnvironmentVariables source code , the EnvironmentVariablesConfigurationProvider resolves the environment as follows.
public override void Load() { Load(Environment.GetEnvironmentVariables()); } internal void Load(IDictionary envVariables) { var data = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); //Here is the screening ASPNETCORE_ Environment variable at the beginning var filteredEnvVariables = envVariables .Cast<DictionaryEntry>() .SelectMany(AzureEnvToAppEnv) .Where(entry => ((string)entry.Key).StartsWith(_prefix, StringComparison.OrdinalIgnoreCase)); foreach (var envVariable in filteredEnvVariables) { //The prefix will be removed and added to the configuration here var key = ((string)envVariable.Key).Substring(_prefix.Length); data[key] = (string)envVariable.Value; } Data = data; }
The keys in IConfiguration are case insensitive. The final effect is to add a record with the key of urls in the global IConfiguration.
If you use the default host CreateDefaultBuilder()ļ¼appsettings. The configuration in JSON will be loaded first.
If in Appsettings If urls is configured in JSON, the environment variable is also defined and will be overwritten by the environment variable.
UseUrls parsing
UseUrls parsing will eventually call UseSetting in GenericWebHostBuilder
//The UseUrls code is as follows 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)); } //UseSetting in GenericWebHostBuilder public IWebHostBuilder UseSetting(string key, string value) { _config[key] = value; return this; }
Because this method is in the new GenericWebHostBuilder(builder);
After that, it is called configure(webhostBuilder); The above code also has instructions. Therefore, if urls in IConfiguration has a value, it will be overwritten. So the highest priority is UseUrls().
Default address
If there are none of the above three configurations, the address is empty, and the default policy will be used. Here is source code , here are the addresses used by the default policy
/// <summary> /// The endpoint Kestrel will bind to if nothing else is specified. /// </summary> public static readonly string DefaultServerAddress = "http://localhost:5000"; /// <summary> /// The endpoint Kestrel will bind to if nothing else is specified and a default certificate is available. /// </summary> public static readonly string DefaultServerHttpsAddress = "https://localhost:5001";
conclusion
- The priority of startup port is set as follows:
Useurls ("XXXX") > environment variables > appsetting JSON configuration URLs > Default Address - Do not replace the global IConfiguration at will. If you do not manually add environment variable resolution, some configuration data will be lost.
- To inject your own configuration into the global, you can use the following methods, which will add the configuration to the global IConfiguration
Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(builder => { builder.UseStartup<Startup>(); }).ConfigureAppConfiguration(config => { config.AddJsonFile("config.json", true, true); }).Build().Run();
Author: cgyqu
source: https://www.cnblogs.com/cgyqu/p/12169014.html
This site uses the creative sharing agreement of "signature 4.0 international". Please indicate the author and source in the obvious position of the article.