Why won't my ASP.NET Core app recognise my user secrets?
I've been working on updating a .NET Framework WCF service to ASP.Net Core using CoreWCF, and everything was going nicely
until I decided to swap out my database connection string from appsettings.json
to dotnet user secrets. I've used user
secrets on a couple of other projects, so was already familiar with doing the setup, which all worked as expected: the
UserSecretsId
attribute was added to the csproj project file, and I set my connection string secret on the commandline
exactly as I'd done in previous projects. According to the
app secrets documentation,
user secrets would be enabled automatically for the Development environment without me having to do anything extra, so it
should all Just Work. So I launch the debug build in Visual Studio, but instead of everything Just Working I get a nasty
exception as soon as something tries to touch the database, and it's quite clear from the logs that the connection string
has not been picked up from user secrets. The entire rest of my afternoon was then consumed trying to debug why.
The docs say user secrets are only enabled in the Development environment, so I double check this and confirm that after
creating my builder with var builder = WebApplication.CreateBuilder(args);
the builder's environment is indeed
Development
, having set a breakpoint so I can inspect it in the Visual Studio Locals window. I also observed that the
expected configuration values were missing in builder.Configuration
, so it seemed that either AddUserSecrets
was not
being called, or it was being called but wasn't working. The internet was not forthcoming with clues, so the next step was
to try calling AddUserSecrets
directly after creating the builder, and after a bit more interneting I figured out how to
do that:
Launch the app, and hey presto: secrets have been found, the builder configuration knows the connection string, and the
app behaves as expected. So why wasn't it working via CreateBuilder
, or CreateSlimBuilder
? After more deep diving
poking into the ASP.NET Core source, I eventually figured out that the builders called AddUserSecrets
using a different
method signature, passing in the Assembly
from which to extract the UUID. So I tried doing that directly:
Launch the app, secrets not found. Poking around at appAssembly in the Locals there clearly wasn't anything there for the
UserSecretsIdAttribute
. Why? It was then that I discovered
this stackoverflow
with the top answer being to check for <GenerateAssemblyInfo>true</GenerateAssemblyInfo>
in the project file, so I take
a look and aha! GenerateAssemblyInfo
was false, so the UserSecretsId
attribute was not being included in the assembly,
causing AddUserSecrets
to fail. Flip GenerateAssemblyInfo
to true, relaunch, and hey presto, fixed forever. I don't
know why GenerateAssemblyInfo
was false before, maybe it made sense to the way the original .NET Framework WCF
implementation was being deployed, but whatever the reason it led to a classic case of an afternoon of debugging for a
simple one-line fix.