65.9K
CodeProject is changing. Read more.
Home

Visual Studio - User Secrets

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.84/5 (13 votes)

Nov 5, 2022

CPOL

3 min read

viewsIcon

20539

Provides a developer’s overview on how to get started with using Visual Studio’s User Secrets

Purpose

I’d like to take a lot of the legwork out for developers, when investigating a new feature like User Secrets.

Covering relevant topics such as overriding appsettings.json files, loading the appropriate appsetting based on the environment (Development for e.g.), how to add\update your secrets.

Scope

The scope of this document is to convey the tasks required to secure sensitive information locally and not within a team code repository (for e.g., a connection string to your LocalDB, which shows your password).

Prerequisites

Why use User Secrets – What Problem Does it Solve

Usually, the settings are placed in the appsettings.json file, but there are settings that we don’t want to share in this file, like passwords, usernames or fully qualified connection strings.

So, the user secrets are used for that, when we only want secrets to be visible to me on my environment.

Create a Console Project

We’ll demonstrate how User Secrets works by implementing a simple Console .NET 6 application.

The new layout of the Console .NET 6 project you will be presented with just a Program.cs with no plumbing in place – here, we will add the code needed:

Add UserSecrets NuGet Package to Project

Add the following NuGet package to your project:

<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" 
                  Version="6.0.1" />

This will, in turn, create an entry in your project properties file called UserSecretsId:

This GUID entry is used to build up the path to the newly created file named secrets.json in your (windows) environment. You won’t see the file inside the solution explorer as it’s saved within your roaming data. The physical path to your secrets.json file (not included in your code check-in) is:

C:\Users\oneillb\AppData\Roaming\Microsoft\UserSecrets\
   050d3b82-cafe-4826-93ed-e156a0ec77be\

Open User Secrets

Right click on your project and select the context menu option Manage User Secrets.

This will open your secrets.json file. Initially, your secrets will be empty, as you have yet to create any entries.

The trick is to keep the same json structure in both the secrets.json and appsettings.json file

Appsettings.json (Development or Production)

Secrets.json

Thus, when you reference the settings, it doesn’t matter which json file is loaded, the composite key will be valid.

Register Appsetting and User Secrets at Start-Up

In the snippet of code below (in your Program.cs file), you are creating what would have been the Configuration method to register your pipeline objects (middleware, dependency injection, for e.g.)

The order that you load your settings in is important, as the last setting referenced will be the one that gets used (last in wins – if two appsetting files get loaded and they both have a common connection string, the last loaded, that connection string will get used.)

In the code above, I am building up one of the Appsetting files, based on the runtime environment setting – see how it is set below (to Development):

NB: If your Appsetting file doesn’t exist – no exception is thrown!

A side note, I am retrieving the Environment variable using the snippet of code below – this is then used to build up the Appsetting file name that I wish to import (I don’t have to import this specific Appsetting – I could load production and override it with my User Secrets).

If I just want to referencing User Secrets in my code:

Reading User Secret Values - Runtime

Once I have loaded the Appsetting and\or User Secrets, and because I have the same json key\value structure within the file, I can make the reference one and it will load the correct setting. There are a couple of ways that I can load the value based on a key.

Retrieving and setting the return type (using the fully qualified json structure):

string fullyQualifiedConnectionString = 
config.GetValue<string>("ConnectionStrings:MyMusicShopConnection"); // read connection

Retrieving a value using the fully qualified json structure:

var fullyQualifiedConnectionStringShortHand = 
    config["ConnectionStrings:MyMusicShopConnection"];

Retrieving a value using the section qualifier (GetConnectionString):

var conString = config.GetConnectionString("MyMusicShopConnection");

Retrieving a root level value:

var userId = config["UserID"]; // no parent & shorthand

Snippet of code used:

Revision History

  • 27th May, 2022: Initial draft (v1)
  • 30th May, 2022: Update - additional topics (v2)