本文主要记录 ASP.NET Core / 通用 Host 下配置加载与密钥存放:环境变量如何切换 appsettings.{Environment}.json、本地 User Secrets 防泄露、以及 dotnet ef 跟随同一套环境变量读连接串。
由 queue 碎片 environment-variables、run-with-config、api-key-user-secrets、ef-generate 合并改写。接 Hello World / MediaInfo 与 EF Core + SQLite。真实 API Key、连接串勿提交 Git。
配置加载机制
默认(Minimal Hosting)大致顺序:
appsettings.json
appsettings.{Environment}.json ← 后加载覆盖前者
环境变量、命令行等(优先级更高,视 Host 默认)
{Environment} 由下列变量决定:
| 变量 | 常见场景 |
|---|---|
ASPNETCORE_ENVIRONMENT | Web / ASP.NET Core |
DOTNET_ENVIRONMENT | Generic Host |
二者都设时,Web 场景通常以 ASPNETCORE_ENVIRONMENT 为准(以当前 SDK 模板行为为准)。未设置时,dotnet run 本地 Web 模板默认多为 Development,因而会加载 appsettings.Development.json。
用环境切换配置文件
PowerShell(当前会话):
$env:ASPNETCORE_ENVIRONMENT = "Production"
dotnet run
CMD:
set ASPNETCORE_ENVIRONMENT=Production
dotnet run
Linux / macOS / WSL:
ASPNETCORE_ENVIRONMENT=Production dotnet run
验证当前环境:在启动日志中查看 Hosting environment,或临时打印 builder.Environment.EnvironmentName。
说明:决定加载哪份 JSON 的是 Hosting Environment,不是 Debug/Release 编译配置。
环境变量速查
以 ASPNETCORE_ENVIRONMENT / DOTNET_ENVIRONMENT 为例。
Windows PowerShell
# 查看
$env:ASPNETCORE_ENVIRONMENT
Get-ChildItem Env: | Where-Object Name -Like "*ASPNET*"
# 临时(当前窗口)
$env:ASPNETCORE_ENVIRONMENT = "Production"
# 永久(用户级,新开终端生效)
[System.Environment]::SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Production", "User")
# 删除会话内
Remove-Item Env:ASPNETCORE_ENVIRONMENT -ErrorAction SilentlyContinue
Windows CMD
echo %ASPNETCORE_ENVIRONMENT%
set ASPNETCORE_ENVIRONMENT=Production
setx ASPNETCORE_ENVIRONMENT Production
setx 只影响新打开的终端。
Linux / macOS
echo $ASPNETCORE_ENVIRONMENT
export ASPNETCORE_ENVIRONMENT=Production
# 持久化可写入 ~/.bashrc 或 systemd unit Environment=
嵌套配置键映射到环境变量时,常用 __ 双下划线,例如 TmdbSettings:ApiKey → TmdbSettings__ApiKey。
User Secrets(本地密钥)
为什么需要
appsettings.json / appsettings.Development.json 若被 Git 跟踪,明文 API Key 极易被扫描盗用。本地开发推荐 User Secrets:密钥写在用户配置目录,不在仓库内。
初始化与写入
在项目根目录:
dotnet user-secrets init
dotnet user-secrets set "TmdbSettings:ApiKey" "<your-api-key>"
init 会在 .csproj 写入 UserSecretsId。密钥物理路径示意:
| OS | 路径 |
|---|---|
| Windows | %APPDATA%\Microsoft\UserSecrets\<UserSecretsId>\secrets.json |
| Linux/macOS | ~/.microsoft/usersecrets/<UserSecretsId>/secrets.json |
仓库内配置可只留占位:
"TmdbSettings": {
"ApiKey": "",
"DefaultLanguage": "zh-CN"
}
读取代码仍用 IConfiguration 键名(如 TmdbSettings:ApiKey),无需为 User Secrets 单独改业务代码。
是否区分 Development / Production?
- 存储层:user-secrets 不按环境分文件,只按
UserSecretsId绑定项目。 - 加载层:默认 Web 模板往往只在
IsDevelopment()时AddUserSecrets,因此 Production 默认不会读本地 secrets。 - 部署到 Docker/服务器时,用环境变量或密钥管理系统注入同名键(如
TmdbSettings__ApiKey)。
查看已设置项:
dotnet user-secrets list
元数据路径配置(示例)
除密钥外,本地数据目录也可放在配置中(非密钥、可进 Development 配置或本机覆盖):
"MediaConfig": {
"MetadataPath": "Z:\\octans_metadata",
"LibraryPaths": {
"Movies": "Z:\\testmovies",
"TvShows": "Z:\\testtvshows"
}
}
Linux 部署可改为 /app/data/octans_metadata 等;大文件目录应挂卷,勿打进镜像层。
EF Core 迁移与环境
dotnet ef database update / migrations add 会启动项目构建 Host 并读 IConfiguration,规则与 dotnet run 相同:依赖当前 ASPNETCORE_ENVIRONMENT(等)选择 appsettings.*.json 与连接串。
# 使用 Production 连接串做迁移(慎用:确认目标库)
$env:ASPNETCORE_ENVIRONMENT = "Production"
dotnet ef database update
ASPNETCORE_ENVIRONMENT=Development dotnet ef database update
注意:
- 连错库会直接改结构,生产前再三确认连接串与环境名。
- 仅 Development 时 User Secrets 中的连接串才可能生效;Production 迁移应依赖显式环境变量或 CI 密钥,而不是本机 secrets。
-- --environment类传参是否被 Host 解析取决于模板;最稳妥是设环境变量(待确认你项目是否自定义了命令行解析)。
验证清单
| 项 | 做法 |
|---|---|
| 环境生效 | 改 ASPNETCORE_ENVIRONMENT 后看加载的 json / 日志中的 environment |
| Secrets | dotnet user-secrets list 有键;仓库内无真实 Key |
| 配置优先级 | 同键时环境变量覆盖 appsettings(默认 Host) |
| EF | 指定环境后 database update 连到预期库(可用只读探测或临时库验证) |
注意事项
- 不要把
secrets.json或含密码的appsettings.Production.json提交进 Git。 - CI/CD 用 runner 密钥或 vault,不复用个人 User Secrets。
- 永久环境变量影响面大,优先会话级
export/$env:做切换。 - 轮换已泄露过的 API Key。