I have a .NET Core 2.1 web API i am hosting locally with IIS. I have two child appSettings.json files, Development and Production. I have also created these environments within my project. My publishing profile uses Debug profile. When I actually debug my code it works perfectly fine.
The issue I have is that when I publish to IIS under a private IP and access it, it seems my code using the wrong appSettings.json file. I know this because I have different file paths used for different environments and it prints out the one from Production.
Even weirder when I physically delete appSettings.Production.json from my inetput/wwwroot/{MyProject} folder, then Postman cannot even talk to the API and I get a 500 bad request. Maybe I am not configuring or linking correctly? This is my first time working with environments.
I have lost about 4 hours on this and I am losing it...
Program.cs
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration(ConfigConfiguration)
.UseStartup<Startup>();
static void ConfigConfiguration(WebHostBuilderContext ctx, IConfigurationBuilder config)
{
config.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appSettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appSettings.{ctx.HostingEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true);
}
Any more info required, do let me know!
Ensure to set the ASPNETCORE_ENVIRONMENT environment variable on the server, see Use multiple environments in ASP.NET Core
.
Related
I have a Worker Service in Net Core 3.1 that reads Production settings from the appsettings.json file and, during development (using the "Debug" build configuration), overwrites appsettings.json settings with appsettings.Development.json, as expected.
I created a build configuration and publish configuration for our QA environment and I want that the appsettings.QA.json file to be merged with appsettings.json at build / publish time. But publishing the project only copies appsettings.json with the production settings without merging with the settings in the aspsetting.QA.json file.
How can I achieve this? I didn't want to copy appsettings.QA.json to the QA environment and set DOTNET_ENVIRONMENT to QA. I would like not to depend on environment variables in this case.
.Net Core does not merge the files into a physical file. They get merged in memory using such block of code in your Program.cs.
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
var env = hostingContext.HostingEnvironment;
config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true)
config.AddEnvironmentVariables();
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
All you need to do is to set the environment variable ASPNETCORE_ENVIRONMENT and .net core will automagically take care of it.
I have an ASP Core 2.2 application which runs fine.
I have an appsettings.json
I have an appsettings.QA.json
I have an Azure App Service which I have added ASPNETCORE_ENVIRONMENT variable to in the Configuration > App Settings section of the portal and set the value to "QA".
I have also added a connection string directly to the Configuration > Connection Strings section of the portal.
When I publish to my Azure App Service, I want to override the settings in appsettings.json with values from appsettings.QA.json. I am struggling to make sense of how this should be configured.
I am reading out the values from the appsettings via the Microsoft.Extensions.Configuration.IConfiguration implementation which is injected into classes where I need such configuration.
So far I have the following:
Program.cs:
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
})
.UseStartup<Startup>();
When the app runs in Azure, it is picking up the connection string from the portal and using it. However, when I read out a value from the appsettings, I always get the value from appsettings.json not appsettings.QA.json.
Can anyone point out how to configure the transforms correctly for an ASP Core 2.2 application?
Am I going about this in the wrong way entirely?
Update
I have removed my custom code above as suggested as it is not needed.
If I output #Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") in my view, I get: "QA;Development". It seems that the "Development" is coming from the web.config which also has ASPNETCORE_ENVIRONMENT set.
you shouldn’t read environment from appsettings. environment is set on machine level and is read at startup.
you have 2 options:
for local machine, set environment variable in launch.settings
in azure, set it in app service configuration as environment variable
ref: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/environments?view=aspnetcore-2.2
I now have this working correctly:
Removed the custom code from the Program.cs as suggested by #KirkLarkin and #dee-zg.
Removed the ASPNETCORE_ENVIRONMENT setting from the Azure portal. The reason for this is that there is also a web.config in the app which has this setting. When reading from the config, it seems that this version is used, not the Azure portal version.
Why is the ASPNETCORE_ENVIRONMENT in the web.config? There is a discussion about this here. Ultimately, what I have done to work around this is to add transforms for the web.config.
Empty/null value returned when attempting to read from the local.settings.json config file when debugging an Azure Function locally using VS2017 for Mac... after scanning the internet I wasn't able to determine if this is a known issue or if there is a work around. This is how I'm accessing the configuration settings:
ConfigurationManager.ConnectionStrings["connName"].ConnectionString
This works fine if the Function app is debugged on a Windows Machine (same git code base)
Azure function v2 running on runtime 2.x(.net core) doesn't support ConfigurationManager any more. See Azure Team's reply on github.
When I debug a v2 function on Windows, System.Configuration.ConfigurationErrorsException thrown. And v1 still works well as you have found.
So as #mariocatch has said, try to read enviroment variables instead.
Two options for you to refer.
Read environment variables directly
string connectionString = Environment.GetEnvironmentVariable("ConnectionStrings:connName");
Add ExecutionContext context to your function method parameters and read local settings.
[FunctionName("FunctionName")]
public static void Run(...,ExecutionContext context)
{
var config = new ConfigurationBuilder()
.SetBasePath(context.FunctionAppDirectory)
.AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
string connectionString = config.GetConnectionString("connName");
.....
}
Have been looking for the right way to add configurations to my dot net core 2.0 web API.
Until now what I have done is:
Added appsetteings.Development.json, appsetteings.Production.json
In program.cs:
public static IWebHost BuildWebHost(string[] args)
{
return WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureAppConfiguration((hostContext, config) =>
{
var env = hostContext.HostingEnvironment;
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
})
.Build();
}
In startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.Configure<dynamic>(Configuration);
}
The issue is whenever I debug my code it always takes settings from appsettings.Development.json.
I also found that the hostContext.HostingEnvironment.EnvironmentName always comes as development regardless of which environment I pick to debug in.
There is a setting with the project properties that is causing the Development environment setting to be used during debug.
Open Project properties
Navigate to the Debug page
In the Environment Variables section you will see:
ASPNETCORE_ENVIRONMENT | Development
If you remove this flag and debug you app it should be running without the Development settings.
The official documentation can be found here
When I deploy my Dot Net Core web app to Azure, the Environment.ContentRootPath variable is set to [myproject]/wwwroot. However, in development, it is just [myproject].
Why does it change in Azure deployment?
How can I make it consistent?
For reference, this is my IWebHost.
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((builderContext, config) =>
{
var env = builderContext.HostingEnvironment;
config.AddJsonFile("appsettings.json", false, true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", true, true);
if (env.IsDevelopment())
config.AddUserSecrets<Startup>();
config.AddEnvironmentVariables();
})
.UseSetting("detailedErrors", "true")
.UseApplicationInsights()
.UseStartup<Startup>()
.CaptureStartupErrors(true)
.Build();
Use KUDU, you could find that your web contents are deployed to D:\home\site\wwwroot as follows:
By default, D:\home\site\wwwroot would be used as the content root and the host would search the content files (e.g. MVC view files,etc.) when hosting your application on Azure Web App.
In development, your app is started from the project's root folder, so the project's root folder is used as the content root.
Per my understanding, you may misunderstand the wwwroot folder in your project with the wwwroot folder on Azure Web App for storing your web content.
Moreover, you could use UseContentRoot to customize your content root folder. If the path doesn't exist, the host would fail to start. Details you could follow Hosting in ASP.NET Core.