新项目必须用iconfiguration读取appsettings.json:一设“复制到输出目录=始终复制”,二用configurationbuilder.addjsonfile显式加载,三通过冒号分层键(如"connectionstrings:default")或绑定poco类安全取值。

新项目一律用 IConfiguration,别碰 ConfigurationManager —— 后者在 .NET Core/5+ 中不工作,硬加引用只会静默失败或运行时报错。
怎么加载 appsettings.json 并确保它真被读到了
不是把文件丢进项目就完事。关键三步:设为“复制到输出目录 = 始终复制”,用 ConfigurationBuilder 显式加载,且必须调用 AddJsonFile 而非手动反序列化。
-
appsettings.json文件属性里,“复制到输出目录”必须是Copy always或Copy if newer,否则运行时根本找不到文件,IConfiguration会跳过它、不报错、只返回null - 手动
File.ReadAllText+JsonSerializer.Deserialize得到的是原始对象,无法支持环境变体(如appsettings.Development.json)、层级键映射(如"Logging:LogLevel:Default")、热重载,也不参与配置源合并 - 标准初始化方式(如
Host.CreateDefaultBuilder())已默认做了这些;若手动构建,需至少包含:.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
读嵌套配置项(比如 ConnectionStrings:Default)的两种写法和坑点
冒号不是语法糖,是 IConfiguration 内部扁平化键名的约定。键 "ConnectionStrings:Default" 和 "ConnectionStrings:Default:Timeout" 在底层都是独立字符串键,靠冒号分层解析。
- 直接用
config.GetValue<string>("ConnectionStrings:Default")</string>最快,但类型不匹配或键不存在时返回default(string)(即null),不会抛异常 —— 所以必须判空 - 用
config.GetSection("ConnectionStrings").GetSection("Default").GetValue<string>("ConnectionString")</string>更清晰,适合多级嵌套,但注意GetSection永远不返回null,哪怕路径不存在,所以后续GetValue仍可能得null - 环境变量覆盖时,键名中冒号要换成双下划线:
ConnectionStrings__Default,且优先级高于appsettings.json
绑定 POCO 类比手拼键名更安全,但有严格命名要求
用 Get<t>()</t> 绑定类能避免拼错键、享受编译期字段检查、自动处理空值,默认值也由属性初始化器或构造函数控制。
- POCO 属性名必须**完全匹配**配置键后缀,区分大小写,不支持驼峰转下划线或自动首字母小写 ——
"Demo:Person:Name"必须对应public string Name { get; set; },不能写成public string name { get; set; } - 嵌套对象可逐层绑定:
config.GetSection("Demo:Person").Get<person>()</person>,比config.GetValue<string>("Demo:Person:Address")</string>更易维护 - 数组或列表需用索引语法:
"info:resource:0"对应 JSON 中"resource": ["a", "b"]的第一个元素
为什么 IConfiguration["key"] 返回 null?常见原因就这三类
不是代码写错了,大概率是配置没加载成功、键名对不上,或类型不匹配却没意识到返回了默认值。
- 文件没复制到输出目录 —— 检查
bin\Debug下有没有appsettings.json,内容是否完整(尤其注意隐藏 BOM 头、尾逗号导致 JSON 解析失败) - 键名大小写或空格不一致 ——
"ConnectionStrings:default"和"ConnectionStrings:Default"是两个键;JSON 值末尾带空格也会原样保留,建议取值后手动.Trim() - 类型不匹配却没处理默认值 ——
GetValue<int>("Logging:LogLevel:Default")</int>若键不存在或值是"Information",返回0而非抛异常,下游逻辑可能因此出错
最易被忽略的一点:配置源合并有固定顺序,后加载的同名键会覆盖前面的。环境变量和命令行参数优先级最高,appsettings.Development.json 次之,appsettings.json 最低 —— 如果你在开发环境改了配置却没生效,先看是不是环境变量在“偷偷覆盖”。











