appsettings.json ↔ Environment Variables
Flatten a .NET configuration file into environment variables - Foo:Bar becomes Foo__Bar - and turn a pasted environment block back into nested JSON. Every shell quotes differently, so pick the platform you are actually pasting into.
appsettings.json
JSONBash / zsh
Windows vs. Linux, macOS, and containers
.NET addresses nested configuration with a colon: Logging:LogLevel:Default. That works as an environment variable name on Windows only. POSIX shells cannot declare an identifier containing a colon at all - export Logging:LogLevel:Default=Trace is a syntax error, not a configuration bug. .NET therefore accepts a double underscore everywhere and translates Logging__LogLevel__Default back into the colon form, which is why __ is the default here.
Arrays use their index as a segment, so Serilog:Using:0 becomes Serilog__Using__0. Indexes have to start at 0 and stay consecutive, otherwise the configuration binder treats the section as an object instead of a list.
Variable names are case-insensitive on Windows and case-sensitive to the OS on Linux and macOS. .NET's own configuration lookup is case-insensitive once the values are loaded, so FEATURE__ENABLED and Feature__Enabled both bind - but two variables that differ only in case will collide on Windows.
Persistence differs per shell. export and $env: last for the current session; set lasts for the current console window; setx is permanent but silently truncates values at 1024 characters and does not affect the window you run it in. A .env file is read by Docker Compose rather than a shell, so nothing in it is expanded or word-split.
Azure App Service prefixes connection strings with SQLCONNSTR_, MYSQLCONNSTR_, SQLAZURECONNSTR_, or CUSTOMCONNSTR_, and surfaces them to .NET under ConnectionStrings:. Turn on the Azure mapping when importing a block copied out of the portal.
Everything runs in your browser - no configuration value, connection string, or password ever leaves this page.
