I have a dotnet console app using webjobs sdk and I´m not able to find how to get the configuration file correctly based on the environment. My code:
static void Main(string[] args)
{
var builder = new HostBuilder();
var environmentName = Environment.GetEnvironmentVariable("environment");
builder.ConfigureHostConfiguration(config =>
{
config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
config.AddJsonFile($"appsettings.{environmentName}.json", optional: true, reloadOnChange: true);
config.AddEnvironmentVariables();
});
...
After that I create 2 files: appsettings.json and appsettings.Production.json. When I´m debugging, even with the variable set to production, I always get the appsettings.json values and not the appsettings.Production.json value. What Im doing wrong here?
Related
I have developed a web API and published it on azurewebsites.net.
I have added the following additional appsettings:-
appsettings.Dev.json
appsettings.Test.json
appsettings.Prod.json
To be able to extract values from these appsettings transforms I made the following code changes:
Tried the solution mentioned here:
https://stackoverflow.com/a/44953524/10485667
Even tried using only the Development/Debug, Staging and Production/Release instead of Dev, Test, Prod receptively. But no luck. It would only publish the values from the main appsettings.json.
Startup.cs
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
#if DEBUG
.AddJsonFile($"appsettings.Dev.json", optional: true)
#endif
.AddEnvironmentVariables();
Configuration = builder.Build();
appSettings = Configuration.Get<AppSettingsModel>().AppSettings;
}
even tried this code:
AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
Tried changing the Program.cs:
public class Program
{
public static void Main(string[] args)
{
var config = new ConfigurationBuilder()
.AddJsonFile($"appsettings.Development.json", optional: true)
.Build();
ILogger logger = null;
var host = CreateWebHostBuilder(args)
.UseConfiguration(config)
.Build();
logger = host.Services.GetService<ILogger>();
host.Run();
}
}
Tried every possible solution provided on internet but no luck. After publishing to azure, it takes the values only from appsettings.json
I think I might be making some conceptual mistake while attempting these solutions. Any kind of help is appreciated.
Thanks in advance
I need to set a Azure Functions app's base directory to the azurewebjobsscriptroot like below, but got exception
var config = new ConfigurationBuilder()
.SetBasePath("%HOME%\site\wwwroot") //error
.AddJsonFile("Settings.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
System.ArgumentException : The path must be absolute. Parameter name:
root at
Microsoft.Extensions.FileProviders.PhysicalFileProvider..ctor(String
root,ExclusionFilters filters) at
Microsoft.Extensions.Configuration.FileConfigurationExtensions.SetBasePath(IConfigurationBuilder
builder,String basePath)
Azure function 2.x
VS 2017
ExecutionContext is null to non-function methods via IoC, alternative to ExecutionContext.FunctionAppDirectory
https://learn.microsoft.com/en-us/azure/azure-functions/functions-app-settings#azurewebjobsscriptroot
You probably want to expand the path first before using it. That way the environment variable(s) embedded in the string can be replaced with the equivalent value of the variable. Resulting in a valid base path for the configuration.
var AzureWebJobsScriptRoot = "%HOME%\site\wwwroot";
var expandedRootPath = Environment.ExpandEnvironmentVariables(AzureWebJobsScriptRoot);
var config = new ConfigurationBuilder()
.SetBasePath(expandedRootPath)
.AddJsonFile("Settings.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
Reference Environment.ExpandEnvironmentVariables(String) Method
I was able to get and use the values from local.setting.json using Environment.GetEnvironmentVariable("test1");
now it's like there is no way to get this file and his values. I only know that another developer that isn't in my team changed something and from then doesn't works anymore... (I can't understand what he changes that can be the problem)
Actually for testing I tried this:
var appSettings = new ConfigurationBuilder()
.SetBasePath(context.FunctionAppDirectory)
.AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
var b = appSettings["test1"];
var c = appSettings["test2"];
var d = Environment.GetEnvironmentVariable("test1", EnvironmentVariableTarget.Machine);
var e = Environment.GetEnvironmentVariable("test1", EnvironmentVariableTarget.User);
var f = Environment.GetEnvironmentVariable("test1", EnvironmentVariableTarget.Process);
var g = Environment.GetEnvironmentVariable("test1");
After this all the variables are null
The local.settings.json
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "",
"test1": "abcd",
"test2": "efgh"
}
}
I'm using visual studio 2017 and the project is Azure Functions, the file local.settings.json it's at the same level of the function.cs.
What could be?
Thank you!
Try the following:
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("local.settings.json", true, true)
.Build();
It may be the case that your context.FunctionAppDirectory may be incorrect. Please also right click the config file -> Configuration -> Advanced => set Copy to output directory to Copy If Newer.
In my case, the contents of the local.settings.json are read by the IConfigurationBuilder however, for some reason they're not loaded on the Environment variables list (Environment.GetEnvironmentVariables()) so the Environment.GetEnvironmentVariable will never read them. So I'm in my Startup class, I manually attached the variables to the current process.
Here's my local.settings.json
{
"Values" : { "Region": "southeastasia" }
}
In my Startup class, here's my IConfigurationRoot:
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables().Build();
And here's how I attached them to the process:
Environment.SetEnvironmentVariable("Region", configuration.GetValue<string>("Values:Region"), EnvironmentVariableTarget.Process);
Now your Environment.GetEnvironmentVariable should look like this:
string region = Environment.GetEnvironmentVariable("Region", EnvironmentVariableTarget.Process);
I want to read environment from command line args and use its value to build Configuration itself. Environment could be passed by different ways (--environment Staging, -e=Staging etc.) so I do not want to parse args myself. I found that we can first build config to read only environment and than build whole configuration:
var envName = new ConfigurationBuilder()
.AddEnvironmentVariables()
.AddCommandLine(args)
.Build()
.GetValue<string>("Environment");
var contentRoot = Directory.GetCurrentDirectory();
var configuration = new ConfigurationBuilder()
.SetBasePath(contentRoot)
.AddJsonFile($"Configuration/appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"Configuration/appsettings.{envName}.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
.AddCommandLine(args)
.Build();
Is there better way to do this?
I am creating some tests using TestServer which is bootstrap with a complex configuration as following:
var config = new ConfigurationBuilder()
.Build();
webHostBuilder = new WebHostBuilder()
.UseConfiguration(config)
.UseKestrel()
.CaptureStartupErrors(true)
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<MockLicenseStartup>()
.UseEnvironment("Development")
.UseUrls("http://locahost");
testServer = new TestServer(webHostBuilder);
Both in my "asp.net core" project and in my test project I have created multiple appsettings.json which is used to provide things like:
Connection String
Log verbosity
Custom Sections
The issue I am facing is that my Configuration class, inside the MockLicenseStartup is not able to load any of the available appsettings.json.
The code used inside MockLicenseStartup.cs is this one:
public MockLicenseStartup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
When I call Configuration.GetConnectionString("") it throws an exception and if I inspect further I can see that no configuration has been loaded actually. Probably is a problem related to the relative/absolute path of .UseContentRoot(Directory.GetCurrentDirectory())
In Test Environment,
.SetBasePath(env.ContentRootPath)
env.ContentRootPath is different from production, it is set to the test project's bin directory if I remember correctly. So, it will not locate the appsettings.json file. unless you copy it there after build.
If you are projects folder structure does not change. you can just try to hard code the appsettings.json" path in these two lines to where these are located.
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true
if this works (it should), you can make it better by find the appsetting.json path in code.
Below is my own code which work in test environment.
var settingFilePath = getSettingFilePath(settingFileParentFolderName: "APIProject");
var builder = new ConfigurationBuilder()
.AddJsonFile(settingFilePath + _settingFileName, optional: true, reloadOnChange: true)
.AddJsonFile(settingFilePath + "appsettings.Development.json", optional: true);
var configuration = builder.Build();
getSettingFilePath() is just a function to locate the setting file path in the Startup Project folder.
Hope this help.