Reputation: 19212
In general, the case sensitivity of .NET Core Environment variables has been a nightmare, especially one you start running Docker containers with .NET Core bits and now I find it rearing its ugly head again, here is a dotnet publish output screenshot:
And here is the source code for appsettings files:
Here is the filename in Visual Studio:
Using git I can prove the "D" in development is indeed upper case for the Windows filename:
Now this issue has also happened to me with appsettings.Production.json and appsettings.Staging.json. It is intermittent. Sometimes case is respected with dotnet publish copies build artifacts to its publish folder yet other times it lowcases the first letter of the environment for some of my appsettings.json files.
I can delete the publish folder to fix the issue when I developing on my machine but once I go to my Linux build server and the dotnet publish takes place on entirely clean Linux slate, where not publish folder existed before the dotnet publish execution I still get the same issue intermittently.
Also, just wanted to point out that that the .NET Core IHostingEnvironment.IsDevelopment()
method is case sensitive, which I cannot believe, but it is so it is more challenging to just setup my code to ignore case, simply because what if another developer trusts IHostingEnvironment.IsDevelopment()
, it is a common .NET Core convention:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment() || env.EnvironmentName.ToLower() == "localhost")
{
app.UseDeveloperExceptionPage();
}
app.UseServiceStack(new AppHost());
}
I could at least do this, to mitigate this case issue:
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName.ToLower()}.json", optional: true, reloadOnChange: true);
But again referring back to the .NET Core convention, of environment case sensitivity this still leaves a "hole" in the plan do to potential I mentioned above, of a developer using IHostingEnvironment.IsDevelopment()
Upvotes: 3
Views: 2297
Reputation: 19212
I wanted to provide the EnvironmentHelper
class, I created to assist with this issue across all my APIs, in case anyone else finds it helpful:
public static class EnvironmentHelper
{
public static bool IsLocalhost(string env)
{
return IsEnvironment(env, EnvironmentName.Localhost);
}
public static bool IsDevelopment(string env)
{
return IsEnvironment(env, EnvironmentName.Development);
}
public static bool IsStaging(string env)
{
return IsEnvironment(env, EnvironmentName.Staging);
}
public static bool IsProduction(string env)
{
return IsEnvironment(env, EnvironmentName.Production);
}
private static bool IsEnvironment(string env, string environmentName)
{
return string.Equals(env, environmentName, StringComparison.CurrentCultureIgnoreCase);
}
}
public static class EnvironmentName
{
public static readonly string Localhost = "Localhost";
public static readonly string Development = "Development";
public static readonly string Staging = "Staging";
public static readonly string Production = "Production";
}
Upvotes: -1
Reputation: 49769
IHostingEnvironment.EnvironmentName
is just a string property and it has both public getter and setter. You as a developer have full control of what value it contains.And in most real cases it just returns the same value as you have in ASPNETCORE_ENVIRONMENT variable.
Based on HostingEnvironmentExtensions.cs implementation:
env.IsDevelopment
using the same IHostingEnvironment.EnvironmentName
internally to get env name, but yes, compares it with EnvironmentName.Development
that contains "Development" as value.
In a general way, you may use IHostingEnvironment.IsEnvironment
method that gets the expected env name as a second parameter.
As the sample, the following code produces the case-insensitive result:
// IHostingEnvironment env;
env.EnvironmentName = env.EnvironmentName.ToLower();
var result = env.IsEnvironment(EnvironmentName.Development.ToLower());
Regarding files, you may do the following:
rename all your config files to lowercase, like appsettings.production.json
modify your code to use env name in lower case only:
.AddJsonFile("appsettings.{env.EnvironmentName.ToLower()}.json")
Upvotes: 2