The User Secrets feature in .NET is a safe, simple way to override values in appsettings.json. The overridden values only exist in a file sitting in your own dev environment, so you don’t accidently commit them to your source control repository.
This feature is enabled in ASP.NET by default, and the framework does most of the work for you. But what if you want to add User Secrets to a console app, or any other project type besides ASP.NET?
There are a few more steps involved to get User Secrets working in a non-ASP.NET project. This article explains how to add and use User Secrets in a console app project.
1 – Add Microsoft.Extensions.Configuration.UserSecrets package
Execute the following in Package Manager Console (View > Other Windows > Package Manager Console).
Install-Package Microsoft.Extensions.Configuration.UserSecrets
Code language: PowerShell (powershell)
This will add the package reference with the latest version to your .csproj file.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="5.0.0" />
</ItemGroup>
</Project>
Code language: HTML, XML (xml)
2 – Add secrets.json
- Right-click on the project > click Manage User Secrets.
- This creates the secrets.json file and opens it.
At this point, it’s just an empty JSON file:
{
}
Code language: JSON / JSON with Comments (json)
3 – Override settings from appsettings.json in secrets.json
Let’s say your appsettings.json looks like this:
{
"ApiKey": "1234",
"Enabled": true,
"Timeout": 5000,
"ConnectionStrings": {
"DefaultDB": "Data Source=ProdServer;Initial Catalog=StocksDB;Integrated Security=SSPI"
}
}
Code language: JSON / JSON with Comments (json)
And you want to override ConnectionStrings. In secrets.json, put the following:
{
"ConnectionStrings": {
"DefaultDB": "Data Source=localhost;Initial Catalog=StocksDB;Integrated Security=SSPI"
}
}
Code language: JSON / JSON with Comments (json)
You can override any settings from appsettings.json by adding to secrets.json. You can also update values in User Secrets programmatically.
4 – Call AddUserSecrets()
Call ConfigurationBuilder.AddUserSecrets(). This makes it load the User Secrets file that you added in the steps above. Any settings that you overrode will be available when you use the Configuration object.
Note: This is assuming you’re already using ConfigurationBuilder and using appsettings.json. If this looks unfamiliar, take a look at this article that explains how to read from appsettings.json in a console app.
using Microsoft.Extensions.Configuration;
class Program
{
static void Main(string[] args)
{
var config = new ConfigurationBuilder()
.SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
.AddJsonFile("appsettings.json")
.AddUserSecrets<Program>()
.Build();
var conString = config.GetConnectionString("DefaultDB");
Console.WriteLine(conString);
}
}
Code language: C# (cs)
When you run this, it outputs the connection string from secrets.json:
Data Source=localhost;Initial Catalog=StocksDB;Integrated Security=SSPI
Code language: plaintext (plaintext)
I’ve noticed that your method is different from the official docs: https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets?view=aspnetcore-5.0&%3Btabs=linux&tabs=windows#register-the-user-secrets-configuration-source
Is there a reason for this? They’re using a HostBuilder.
Hi Xavier.
Good question. The official docs are assuming you’re building a console app using a .NET Generic Host (which basically provides patterns that people are used to in ASP.NET projects). If you’re using a .NET Generic Host, you’d use HostBuilder with ConfigureAppConfiguration() and then dependency inject IConfiguration into your hosted service class.
In this article, I’m not using .NET Generic Host. Instead, it’s just a plain and simple console app. So far, I haven’t run into a real world scenario where I’d use the .NET Generic Host for a simple console app. I’m sure there are legitimate use cases for it – I just haven’t had the need for it yet.
So the short answer: if you’re building a simple console app, you can use the approach shown in this article to use User Secrets. If you’re building a console app and want to use the .NET Generic Host feature, use HostBuilder.
-Mak
I too have not found a reason to use Generic Host scaffolding for a console application. In many of the documents I found for reading the Secrets Json file from a console application involved DI and Configuration Host. My app in all is less than 20 lines of executable code. Setup up for Generic Host would require more code in just reading the secrets than what is needed to process so… thanks Mak
Keeping it simple, good to hear! Thanks Max.
How do you get a config value that’s not a connection string?
Good question, Josh.
You may be interested in reading through this: How to read custom configurations from appsettings.json, specifically the last part about how to read a single value from appsettings.json.
I am not sure where you’re getting your info, but great topic.
I get my info from researching, experimenting, and from first-hand experience on projects. Same as anyone, I hope, unless they’re somehow making it up 😛