在.NET Core以及后续的.NET项目中,配置系统已经和传统的ConfigurationManager彻底分家。现在应用程序的配置来自一组称为“配置提供器”的组件,appsettings.json只是其中之一。程序启动时,通用主机或Web主机把多个配置源按优先级叠加,最终组装成一个IConfiguration对象。我们平时说的“读取appsettings.json”,本质上是从这个合并后的配置对象里按路径取数据。

基础用法:注入IConfiguration直接取值
最常见的场景是在ASP.NET Core的控制器或服务里读取配置。框架默认在Program.cs中调用了AddJsonFile("appsettings.json"),因此我们不需要手动加载文件,只要在类的构造函数里声明IConfiguration参数,依赖注入容器就会自动传进来。
假设appsettings.json内容如下,其中包含一个顶层字符串和一个嵌套对象:
{
"AppName": "DemoApp",
"Database": {
"Host": "127.0.0.1",
"Port": 5432
}
}
在控制器中可以通过索引器或GetSection方法获取对应的值。索引器使用冒号分隔的层次路径,这点和旧版Web.config的AppSettings写法不同,需要注意不要写成斜杠。
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
[ApiController]
[Route("api/config")]
public class ConfigController : ControllerBase
{
private readonly IConfiguration _configuration;
public ConfigController(IConfiguration configuration)
{
_configuration = configuration;
}
[HttpGet]
public IActionResult Get()
{
// 读取顶层配置
var appName = _configuration["AppName"];
// 读取嵌套配置,使用冒号分隔
var dbHost = _configuration["Database:Host"];
var dbPort = _configuration["Database:Port"];
return Ok(new { appName, dbHost, dbPort });
}
}
这种写法简单直接,适合配置项较少的情况。但缺点也很明显:字符串键名分散在代码各处,一旦json结构微调就容易漏改;而且取出来的值都是字符串,数字或布尔还得自己转换。
如果只需要某个节点下的少数几个值,也可以用GetSection配合GetValue扩展方法,并指定目标类型,减少手动转换的麻烦。
using Microsoft.Extensions.Configuration;
var dbSection = _configuration.GetSection("Database");
int port = dbSection.GetValue<int>("Port");
string host = dbSection.GetValue<string>("Host");
进阶做法:绑定到强类型配置类
当配置节点变多,更好的方式是定义普通C#类,把整段配置映射成对象。这样既能在编译期发现字段拼错,也方便做单元测试时传入模拟数据。
先声明一个与json结构匹配的类,字段名不区分大小写,框架默认使用忽略大小写的绑定:
public class DatabaseOptions
{
public string Host { get; set; }
public int Port { get; set; }
}
public class AppSettings
{
public string AppName { get; set; }
public DatabaseOptions Database { get; set; }
}
在Program.cs里通过AddOptions和GetSection完成绑定注册,之后就能以IOptions<AppSettings>的形式注入使用。这种方式把配置读取和json文件解耦,以后换成环境变量或命令行提供数据,业务代码完全不用动。
// Program.cs 中注册
builder.Services.Configure<AppSettings>(builder.Configuration);
// 在控制器或服务中使用
public class HomeController : Controller
{
private readonly AppSettings _settings;
public HomeController(IOptions<AppSettings> options)
{
_settings = options.Value;
}
public IActionResult Index()
{
var host = _settings.Database.Host;
return Content(host);
}
}
使用强类型配置时,如果希望配置热更新(修改json文件后不用重启程序),可以把IOptions换成IOptionsSnapshot或IOptionsMonitor。前者在每次请求时重新读取,后者可监听变更并触发回调,适合常驻后台服务。
需要注意,默认json提供器开启reloadOnChange后,文件保存即生效,但绑定到POCO的对象只有在通过Snapshot或Monitor解析时才会拿到新值,直接用IOptions.Value拿到的是启动时的快照。
非Web项目与手动加载文件
如果是控制台程序或类库,没有现成的主机帮我们注册配置,就要自己用ConfigurationBuilder搭一遍。下面代码演示如何从程序运行目录加载appsettings.json:
using Microsoft.Extensions.Configuration;
using System.IO;
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
IConfiguration config = builder.Build();
string name = config["AppName"];
SetBasePath决定了相对路径从哪里算,很多初学者把json放在项目根目录却忘了设基路径,导致发布后找不到文件。建议把文件设为“如果较新则复制”,保证输出目录里有它。
另外,配置提供器有先后顺序。后添加的源会覆盖前面的同名键。比如先AddJsonFile再AddEnvironmentVariables,那么环境变量里的同名配置优先。调试时发现读到的不是json里的值,多半是被环境变量或启动设置覆盖了。
常见误区与排查建议
第一个误区是以为ConfigurationManager.AppSettings还能用。.NET Core已经移除这个静态类,继续引用会编译报错或拿到空值。所有读取都应走注入的IConfiguration或IOptions。
第二个误区是在构造函数里直接读IConfiguration.GetSection(...).Value却得到null。通常原因是appsettings.json里节点名拼错,或者文件没复制到输出目录。可以在调试时把_configuation当成对象展开,看实际加载了哪些键。
| 问题现象 | 可能原因 | 解决办法 |
|---|---|---|
| 读取结果为null | json文件名或节点路径错误 | 核对文件名,使用冒号路径 |
| 修改json不生效 | 用了IOptions而非Snapshot | 改用IOptionsSnapshot或重启 |
| 发布后找不到文件 | 未设置复制到输出目录 | 文件属性改为较新则复制 |
只要理清配置提供器叠加机制和注入方式,C#读取appsettings.json其实非常顺手。把变化频繁的开关放配置里,把结构稳定的参数绑成强类型,就能兼顾灵活与可维护性。
C#appsettings_json.NET_Core修改时间:2026-08-01 13:36:30