'Problems with user secrets in .Net console apps
I've created a .Net 6 console app. I added user secrets, but I only get the values defined in the appsettings.json file. I use Visual Studio Professional 2022 version 17.0.4.
Initial steps
- Create a new .Net 6 console app from Visual Studio 2022's project templates.
- Install the Microsoft.Extensions.Hosting nuget package (version 6.0.0).
- Install the Microsoft.Extensions.Configuration.UserSecrets nuget package (version 6.0.0).
- Add the appsettings.json file and set Copy to Output Directory to Copy always.
- Right-click on the project and select Manage User Secrets.
Code
Program.cs
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var host = Host.CreateDefaultBuilder()
.ConfigureServices((context, services) =>
{
services.Configure<GlobalSettings>(context.Configuration.GetSection("GlobalSettings"));
services.AddTransient<Worker>();
})
.Build();
var work = host.Services.GetRequiredService<Worker>();
await work.ExecuteAsync();
Worker.cs
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
public class Worker
{
private readonly ILogger<Worker> _logger;
private readonly GlobalSettings _globalSettings;
public Worker(ILogger<Worker> logger, IOptions<GlobalSettings> globalSettings)
{
_logger = logger;
_globalSettings = globalSettings.Value;
}
public async Task ExecuteAsync()
{
_logger.LogInformation(_globalSettings.Foo);
_logger.LogInformation(_globalSettings.Bar);
await Task.CompletedTask;
}
}
GlobalSettings.cs:
public class GlobalSettings
{
public string Foo { get; set; }
public string Bar { get; set; }
}
.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>disable</Nullable>
<UserSecretsId>deedd476-f5d6-47f4-982e-1645c89789c7</UserSecretsId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.0" />
</ItemGroup>
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
appsettings.json:
{
"GlobalSettings": {
"Foo": "Normal Foo",
"Bar": "Normal Bar"
}
}
secrets.json:
{
"GlobalSettings": {
"Foo": "Secret Foo",
"Bar": "Secret Bar"
}
}
What I've tried
- Checked whether the user secret id in csproj matched the folder, which it did: C:\Users\Dennis\AppData\Roaming\Microsoft\UserSecrets\deedd476-f5d6-47f4-982e-1645c89789c7
- Rebuilded the project.
- Closed Visual Studio 2022 and ran it again as administrator.
- Created a new project from scratch.
- Compared the code with one of my colleague's projects. I couldn't find any difference, but his code works when I run it.
- Changed IOptionsSnapshot to IOptions and IOptionsMonitor.
- Changed AddTransient to AddSingleton.
- Did the same steps, but with a .Net 5 project instead.
Thanks.
Solution 1:[1]
I'd misunderstood the way the Host.CreateDefaultBuilder method worked. According to the documentation (docs):
load app IConfiguration from User Secrets when EnvironmentName is 'Development' using the entry assembly
My environment is Production (probably a fallback value). It worked in my colleague's project because it included a launchSettings.json file with the DOTNET_ENVIRONMENT environment variable set to Development.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |