.NET Core+项目必须用IConfiguration读取appsettings.json,ConfigurationManager仅适用于.NET Framework;app.config在新版本中被忽略,且不支持热重载。

app.config 用 ConfigurationManager 还是 AppContext?
.NET Framework 项目默认用 ConfigurationManager,但 .NET Core / .NET 5+ 已移除它,强行引用 System.Configuration.ConfigurationManager NuGet 包仅能读取 app.config(非 web.config),且不支持配置热重载。别在新项目里硬套旧方式。
关键判断:如果你用的是 .NET Core 3.1 或更新版本(包括 .NET 5/6/7/8),app.config 实际上被忽略,系统默认找 appsettings.json —— 即使你手动加了 app.config 文件,ConfigurationManager.AppSettings 也会返回空。
- 旧项目(.NET Framework):用
ConfigurationManager.AppSettings["key"]或ConfigurationManager.ConnectionStrings["name"] - 新项目(.NET Core+):必须用
IConfiguration接口,靠Host.CreateDefaultBuilder()自动加载appsettings.json和环境变体 - 混合项目(如 .NET Standard 类库):不能直接用
ConfigurationManager,需由宿主程序注入IConfiguration
appsettings.json 的标准加载路径和优先级
IConfiguration 默认按固定顺序合并多个源,顺序靠后的值会覆盖前面的同名键。典型顺序是:
-
appsettings.json(基础配置) -
appsettings.{Environment}.json(如appsettings.Development.json) - 环境变量(
ASPNETCORE_ENVIRONMENT=Development) - 命令行参数(
--MySection:MyKey value)
注意:appsettings.json 必须设为“复制到输出目录 = 始终复制”,否则运行时找不到文件,IConfiguration 会静默跳过,读出来全是 null 或默认值。
常见错误现象:configuration["Logging:LogLevel:Default"] 返回 null,但 JSON 里明明写了 —— 八成是文件没复制过去,或 JSON 格式有隐藏逗号、尾逗号、Unicode BOM 头导致解析失败。
读取嵌套结构(如 ConnectionStrings 或自定义 Section)
别用字符串拼接键名去逐层取值,容易写错、难维护、无法享受类型安全。正确做法是绑定到 POCO 类:
public class DatabaseSettings
{
public string ConnectionString { get; set; }
public int TimeoutSeconds { get; set; }
}
然后在 Program.cs 中注册:
builder.Services.Configure<DatabaseSettings>(builder.Configuration.GetSection("Database"));
使用时注入 IOptions<DatabaseSettings> 或 IOptionsSnapshot<DatabaseSettings>(后者支持热重载)。如果只是临时读一下,也可直接用:
-
configuration.GetSection("Database").Get<DatabaseSettings>()(一次性读取) -
configuration.GetConnectionString("Default")(专用于ConnectionStrings节)
注意:GetConnectionString() 只查根级 ConnectionStrings 对象,不支持子路径;若 JSON 里写成 "ConnectionStrings": { "Db": { "ConnectionString": "..." } },它就读不到 —— 必须是扁平结构:"ConnectionStrings": { "Db": "server=..." }。
跨平台读取失败的三个隐蔽原因
Windows 上跑得好好的配置,Linux/macOS 容器里突然读不到,往往不是代码问题,而是环境细节:
- JSON 文件编码:保存为 UTF-8 无 BOM,BOM 会导致
JsonConfigurationProvider解析失败且不报错 - 大小写敏感:Linux 文件系统区分大小写,
AppSettings.json≠appsettings.json;确保文件名全小写 - 路径分隔符硬编码:不要写
File.ReadAllText("config\appsettings.json"),用Path.Combine("config", "appsettings.json")或直接依赖默认加载逻辑
最稳妥的做法,永远优先走 IConfiguration 的默认管道,而不是自己手写 File.ReadAllText + JsonSerializer.Deserialize —— 后者绕过了环境变量、层级合并、热重载等关键能力,还容易引入权限、路径、编码问题。










