I have a .NET Core 2.0 Web API that is failing to read the environment specific app.settings file. As far as I can tell I have followed all the relevant steps.
This is my Startup.cs constructor:
public Startup(IHostingEnvironment env)
{
var config = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables();
}
I then have an appsettings.json file structure of:
appsettings.json
-appsettings.debug.json
-appsettings.release.json
-appsettings.production.json
And on the server where my API is deployed to I have a system environment variable key/value pair of
Variable = ASPNETCORE_ENVIRONMENT Value = Release
But when I make calls into the API the appsettings.production.json values are used, which (from what I understand) is the default when an environment variable of ASPNETCORE_ENVIRONMENT is not found.
Thoughts on what my setup might be missing to cause this default behavior?
You haven't specified, but I'm assuming your running in IIS. If that's the case, you need to edit the advanced properties of your App Pool and set the "Load User Profile" option to true. Otherwise, it won't actually read from your environment variables.
Related
I've an Asp.Net Core application.
When we first launch it, the code check for some variable in it, and if missing, it displays a wizard, which allow our users to configure some stuff. Those configured element are then stored in this appsettings.json(could be SMTP settings, mongo db settings, ...) and the app is restarted to take those into account.
This part work fine. The issue is that this file gets commited by every developer on every change, and some things are referencing things that are local(could be the schema version of our database, or some folder). We tried to put this file in the git ignore list, but since there are some settings(like log level) that are present(and should stay present), the file needs to be presents and its updates are tracked.
So I'm wondering: Is there a way to have some sort of "template" of appsettings.json, like initial.appsettings.json, and when the Asp.Net Core app starts, check if the file is missing, copy it and restart if needed?
Like this we can have this initial.appsettings.json being tracked, and ignore the appsettings.json in our git repository?
After test, the coon value will be overriden by the settings in connectionstrings.json file. You can find it below.
Splitting the files in appsettings.json is a good option for your current situation.
You can divide the configuration in the appsettings.json file into connectionstrings.json, and logging.json according to your requirements.
var builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile("connectionstrings.json", optional: true, reloadOnChange: true)
.AddJsonFile("logging.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables();
Load it at startup with the following code. Then you are ignoring which specific files according to your needs.
I have created an Azure Function v2. In most articles I people suggest following:
var config = new ConfigurationBuilder()
.SetBasePath(context.FunctionAppDirectory)
.AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
Does a function hosted on azure also have a local.settings.json file? Will this code snippet get the app settings defined in Azure? Or do you need to change local.settings.json before publish? I thought local.settings.json was a local developer thing?
Is there any recommended practices using above snippet vs
Environment.GetEnvironmentVariable("xx")?
The first way you posted works just fine, both locally and in the cloud.
Note: In Azure, there is no local.settings.json (or should never be). This is only being used when debugging locally. There it is being picked up by the Functions runtime the same way it picks up AppSettings when running in Azure - and the settings are injected into your app as env variables. I have been using this for most of the time.
However, I recently started to switch to the second way, using Environment variables (Environment.GetEnvironmentVariable("xx")). Why? Simply because it is shorter and requires not extra usings etc. Apart from that there is no difference that I am aware of in using either of those ways.
I'm trying to create a super basic Azure Function, but am having trouble with environment variables. Following various tutorials online,
var config = new ConfigurationBuilder()
.SetBasePath(context.FunctionAppDirectory)
.AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
log.Info(config["AzureWebJobsStorage"]);
My local.settings.json looks like this:
{
"IsEncrypted": false,
"Values": {
"FUNCTIONS_WORKER_RUNTIME": "<language worker>",
"AzureWebJobsStorage": "abc123",
"AzureWebJobsDashboard": "abc123",
"MyBindingConnection": "abc123"
},
"Host": {
"LocalHttpPort": 7071,
"CORS": "*"
}
}
When I run this locally, that
log.Info(config["AzureWebJobsStorage"]);
line returns nothing... but when I deploy to Azure I see "abc123" in the console.
If, however, I alter that line to
log.Info(config["Values:AzureWebJobsStorage"]);
Then when I run locally, I see "abc123" but when I deploy to Azure I see nothing.
Is there something I'm missing to be able to reach the environment variables the same way locally vs deployed?
EDIT: To clarify, these settings are configured in the app settings for the function:
Assuming you are using targeting the ~2 runtime for your Azure Functions you can access your configuration values through:
log.Info(Environment.GetEnvironmentVariable("AzureWebJobsStorage", EnvironmentVariableTarget.Process));
Those environmental variables work when you are testing your function locally. However, when you deploy to the Azure Function Portal, you need to setup your variables using their built-in system to handle Environmental Variables.
Copy and past your key-values into the sections that I highlighted in the image below.
<
I'm creating integration tests for ASP.NET Core WebAPI. I'm trying to make TestServer to use real, NOT in memory, sql-server database.
The first problem was, that WebHostBuilder didn't see connection string in "connectionstring.json", so I moved connection string cofnig to "appsettings.json". Now WebHostBuilder loads the connection string from appsettings.json file, but it doesn't load any data from sql-server database when executing a query (returns empty collection). It does, when I run it normally (not as testserver) and do GET through Postman.
My question is: "Is it possible to make TestServer to use sql-server database and how to do it?"
I found a similar question here call api Test server : .net core API integration tests , but there is no answer how to make TestSever works with sql-server database.
TestServer:
_server = new TestServer(WebHost.CreateDefaultBuilder()
.UseEnvironment("Development")
.ConfigureAppConfiguration(AddConfigFiles)
.UseStartup<Startup>()
);
AddConfigFiles method:
public static void AddConfigFiles(WebHostBuilderContext hostingContext, IConfigurationBuilder config)
{
var env = hostingContext.HostingEnvironment;
config
.AddJsonFile("connectionstrings.json", optional: true)
.AddJsonFile($"connectionstrings.{env.EnvironmentName}.json", optional: true)
.AddJsonFile("appsettings.json", optional: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
config.AddEnvironmentVariables();
}
Connection string
"Data Source={MyServerName};Initial Catalog={MyDatabaseName};Integrated Security=True;"
Yes it is possible, if you want to see a full setup look at this answer: https://stackoverflow.com/a/54858071/2482439
In the example, the database used is SQLite but you can change the DatabaseType configuration to use SQL Server or any other.
Remember that the configuration files must be in the folder of the test project that are currently executing the tests, the scope, the path is defined by that.
So if you have Project.Integration.Tests, in the root folder you need to have connectionstrings.Development.json and appsettings.Development.json.
Also, you should probably set required true, for those config you really need.
We have set custom environment variables in the Elastic Beanstalk dashboard, under configuration=>software configuration=>"Environment Properties" section. In a C# MVC 5 project, we can just access these variables by looking for them with ConfigurationManager.AppSettings - that works great.
In .NET core, however, we don't use web.config anymore. We've been attempting to track down a way to access the environment variables, but all we've found is a nuget package called AWSSDK.Extensions.NETCore.Setup. However, this package does not seem to get us the access to the custom variables.
Any help would be greatly appreciated.
Based on my research and testing, this is a deficiency in AWS Elastic Beanstalk for ASP.NET Core 1.1 applications. Just ran into this issue today and the only way to solve it is to load the config that AWS writes (if it's there) using the ASP.NET ConfigurationBuilder and parse it.
AWS should eventually fix this, until then you can use the method I'm using:
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddJsonFile(#"C:\Program Files\Amazon\ElasticBeanstalk\config\containerconfiguration", optional: true, reloadOnChange: true)
.AddEnvironmentVariables();
var config = builder.Build();
builder.AddInMemoryCollection(ParseEbConfig(config));
Configuration = builder.Build();
}
private static Dictionary<string, string> ParseEbConfig(IConfiguration config)
{
Dictionary<string, string> dict = new Dictionary<string, string>();
foreach (IConfigurationSection pair in config.GetSection("iis:env").GetChildren())
{
string[] keypair = pair.Value.Split(new[] { '=' }, 2);
dict.Add(keypair[0], keypair[1]);
}
return dict;
}
Previously, Elastic Beanstalk didn't support passing environment variables to .NET Core applications and multiple-application IIS deployments that use a deployment manifest [1]. The Elastic Beanstalk Windows Server platform update on June 29, 2020 [2] now fixes this gap. For details, see Configuring your .NET environment in the Elastic Beanstalk console [3].
[1] https://docs-aws.amazon.com/elasticbeanstalk/latest/dg/dotnet-manifest.html
[2] https://docs.aws.amazon.com/elasticbeanstalk/latest/relnotes/release-2020-06-29-windows.html
[3] https://docs-aws.amazon.com/elasticbeanstalk/latest/dg/create_deploy_NET.container.console.html#dotnet-console