跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

c#如何读取appsettings.json_c#读取appsettings.json新手必看入门教程

根本原因是 IConfiguration 未正确加载 appsettings.json:手动构建 ConfigurationBuilder 时漏掉 AddJsonFile,或路径/环境变量配置错误导致文件未加载。 为什么
Configuration.GetSection("xxx")
返回 null? 不是配置写错了,大概率是没把
appsettings.json
正确加载进
IConfiguration
。.NET 6+ 默认模板会自动调用
Host.CreateDefaultBuilder()
,它内部已注册
appsettings.json
和
appsettings.{Environment}.json
,但如果你手动构建
ConfigurationBuilder
(比如在单元测试或控制台工具里),必须显式加:
var config = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .Build();
漏掉
AddJsonFile
这一行,所有读取都返回
null
或默认值。 常见坑:
optional: false
表示文件必须存在,设为
true
时即使文件缺失也不报错,但后续读不到配置——容易误以为“读取成功”
reloadOnChange: true
在开发期有用,但发布到 IIS 或 Linux 容器时,文件权限或监视机制可能失效,别依赖它自动刷新 路径用
Directory.GetCurrentDirectory()
不一定对:ASP.NET Core Web 项目默认工作目录是项目根,但控制台或类库中可能是 bin 输出目录,建议用
AppContext.BaseDirectory
更稳 怎么安全读取嵌套对象(比如数据库连接字符串)? 别直接用
config["ConnectionStrings:Default"]
拼字符串键——大小写、冒号、空格一错就静默失败。推荐用强类型绑定:
public class DatabaseOptions { public string ConnectionString { get; set; } = string.Empty; public int TimeoutSeconds { get; set; } = 30; }
然后在
Program.cs
注册:
builder.Services.Configure(builder.Configuration.GetSection("Database"));
使用时通过
IOptions
或
IOptionsSnapshot
注入。注意:
IOptions
是单例,启动后不再响应
appsettings.json
文件变更;
IOptionsSnapshot
每次请求新建实例,支持热重载(但仅限
reloadOnChange: true
且文件实际被修改时) 如果配置节不存在(比如
"Database"
根本没写),
GetSection
返回非
null
的空节,绑定后对象字段全是默认值——不会抛异常,得自己校验
string.IsNullOrEmpty(options.ConnectionString)
不推荐用
ConfigurationBinder.Bind()
手动绑定,它绕过 DI 生命周期,也难测
GetValue()
和
GetSection().Get()
有什么区别? 前者读单个原始值(如字符串、数字、布尔),后者读整个对象结构。例如: 稿定在线PS PS软件网页版 下载
// appsettings.json 中: // "LogLevel": "Warning" // "Features": { "EnableCache": true, "MaxRetries": 3 }

var level = config.GetValue("LogLevel"); // OK,返回 "Warning" var features = config.GetSection("Features").Get(); // OK,返回新对象

关键差异:
GetValue()
要求键路径精确匹配一个 JSON 值,不能指向对象或数组,否则返回
default(T)
且无提示
GetSection("x").Get()
要求
T
是 class 或 record,且属性名需与 JSON 字段名匹配(默认忽略大小写,但建议保持 camelCase 一致) 两者都不支持自动转换枚举:如果 JSON 写
"Status": "Active"
,而 C# 属性是
Status { get; set; } = StatusEnum.Inactive
,绑定后仍是默认值,不会解析字符串为枚举项 环境配置(
appsettings.Development.json
)为啥不生效? 核心只看一个值:
DOTNET_ENVIRONMENT
环境变量(或
ASPNETCORE_ENVIRONMENT
,后者仅 ASP.NET Core 有效)。它决定了
CreateDefaultBuilder()
加载哪个
appsettings.{env}.json
。 验证方法:在代码里打日志
Console.WriteLine($"Env: {Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT")}");
常见问题: VS 调试时没设环境变量——右键项目 → “属性” → “调试” → “环境变量” 添加
DOTNET_ENVIRONMENT=Development
Docker 运行时忘记传:启动容器要加
-e DOTNET_ENVIRONMENT=Production
代码里硬编码了
Environment.SetEnvironmentVariable()
,但它只影响当前进程,且必须在
Host.CreateDefaultBuilder()
之前调用才有效
appsettings.Development.json
的优先级高于
appsettings.json
,但低于命令行参数和环境变量——如果命令行传了
--Logging__LogLevel__Default=Debug
,它会覆盖 JSON 里的设置 多环境配置最易被忽略的点:不同环境的配置节结构最好保持一致。比如 Development 里写了
"Cache": { "Enabled": true }
,Production 却删了整个
"Cache"
节,那绑定到对象时该字段就是默认值,运行时才暴露问题。

相关文章