一句话分界:
runtimeconfig.json = CLR运行时行为配置(对标 .NET Framework machine.config 里的
<runtime>) appsettings.json = 业务应用配置(对标 .NET Framework app.config/web.config 的 appSettings、connectionStrings) ✅ .NET Core / .NET 5+ 没有全局 machine.config,所有运行时策略跟着单个应用走,天然隔离,这是最大区别
一、核心区分表
| 项目 | runtimeconfig.json | appsettings.json |
|---|---|---|
| 管控对象 | CLR运行时本身 | 业务程序逻辑 |
| 读取方 | .NET Core Host / dotnet.exe(托管层之前) | IConfiguration、IOptions(托管代码内读取) |
| 典型配置 | GC模式、程序集绑定、AppContext开关、兼容开关、roll-forward策略 | 连接串、日志、开关、第三方SDK参数、接口地址 |
| 作用域 | 单个应用程序,每个exe独立一份 | 单个应用,可多环境文件叠加 |
| 能否代码读取 | 托管代码不能直接读,CLR原生解析 | 业务代码随时读取、绑定实体 |
| 热更新 | 修改后必须重启进程才生效 | 默认 reloadOnChange:true,可热加载(IOptionsSnapshot) |
| 生成时机 | 编译自动输出 AppName.runtimeconfig.json | 手动编写,复制到输出目录 |
第一部分:runtimeconfig.json 详解
1. 文件名称 & 来源
编译后输出目录:{程序集名称}.runtimeconfig.json 配套模板:runtimeconfig.template.json(放在项目目录,编译时自动合并进最终 runtimeconfig.json,推荐在这里维护,不要直接改bin下生成文件)
项目csproj控制开关:
xml
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
SDK项目默认true,大部分场景不用动。
2. 完整标准模板
json
{
"runtimeOptions": {
"tfm": "net8.0",
"framework": {
"name": "Microsoft.NETCore.App",
"version": "8.0.10"
},
"rollForward": "LatestMinor",
"applyPatches": true,
"configProperties": {
"System.GC.Server": true,
"System.GC.Concurrent": true,
"System.GC.HeapCount": 4,
"Switch.System.Net.DontEnableSchUseStrongCrypto": false,
"Switch.System.Security.Cryptography.UseLegacyFipsThrow": false,
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false
}
}
}
节点解释
- tfm:Target Framework Moniker,目标框架,如 net6.0 / net7.0 / net8.0
- framework:指定共享框架包
- name:
Microsoft.NETCore.App(基础运行时);ASP.NET项目还有Microsoft.AspNetCore.App - version:期望的运行时版本
3.rollForward 版本回滚策略(非常高频,部署坑点)
-
LatestPatch:只升补丁版本,小版本、主版本不动(最保守)LatestMinor:优先同主版本最新小版本(默认)LatestMajor:允许跨主版本Disable:严格匹配指定version,版本不对直接报错无法启动
4.applyPatches:是否自动使用安装的补丁更新包
5.configProperties 【核心】→ 对标 Framework machine.config <runtime> 这里放所有CLR开关、GC、AppContext开关,完整官方可查清单:.NET runtime config properties
高频 configProperties 清单
json
"System.GC.Server": true, // 服务器GC(IIS、后端服务)
"System.GC.Concurrent": true, // 并发GC
"System.GC.RetainVM": true,
"System.Threading.ThreadPool.MinThreads": 8,
"System.Threading.ThreadPool.MaxThreads": 100,
"Switch.System.Net.DontEnableSchUseStrongCrypto": false,
"Switch.System.Data.AllowUnsafeCode": false,
"System.Runtime.Loader.AllowCollectibleAssemblies": true
3. runtimeconfig 优先级(由低→高,后者覆盖前者)
- runtimeconfig.json / template.json
- csproj 里 MSBuild 属性(
<RuntimeConfigProperty>) - 环境变量(DOTNET_ 前缀, .NET9开始环境变量优先级最高)
- 代码
AppContext.SetSwitch()(进程内,代码启动后)
⚠️ 没有机器全局runtimeconfig!想整机统一GC策略:只能靠系统环境变量 DOTNET_ *,对本机所有dotnet程序生效。
4. 程序集绑定(对应Framework assemblyBinding)
.NET Core 不再使用xml bindingRedirect,分两种模式:
- 依赖项版本自动选择(默认) :NuGet解析、运行时按依赖图自动选版本
- 手动版本重定向:在csproj用
<PackageReference>+<Version>或者<BindingRedirects>,不再写在runtimeconfig.json> > fuslogvw 对 .NET Core 依然可用,但日志位置、格式不一样。
第二部分:appsettings 体系(IConfiguration 配置体系)
这是一套可扩展配置提供器模型 ,不是单纯读json文件,json只是其中一个源。 ASP.NET Core
Host.CreateDefaultBuilder()/ .NET6+Host.CreateApplicationBuilder()内置默认加载流程
1. 默认加载顺序(优先级从【低】→【高】,后加载覆盖前面同Key)
重点规则:后加入的Provider覆盖前面Provider的相同键
appsettings.json(基础公共配置)appsettings.{Environment}.json(环境差异化,例如 appsettings.Production.json / appsettings.Development.json)- 用户机密 UserSecrets(仅 Development 环境,开发本地密钥,不提交git)
- 环境变量
- 命令行参数 args(最高优先级,运维临时覆盖)
环境变量名称规则:
__双下划线替代层级冒号:例:ConnectionStrings__Default等价于Configuration["ConnectionStrings:Default"]
2. 文件示例 appsettings.json
json
{
"ConnectionStrings": {
"Default": "Server=127.0.0.1;Database=test;Uid=xxx;Pwd=xxx"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"App": {
"ApiUrl": "[https://api.xxx.com](https://api.xxx.com)",
"MaxBatch": 100
}
}
appsettings.Development.json(开发环境,覆盖上面)
json
{
"ConnectionStrings": {
"Default": "Server=127.0.0.1;Database=test_dev;Uid=xxx;Pwd=xxx"
},
"App": {
"ApiUrl": "[https://dev-api.xxx.com](https://dev-api.xxx.com)"
}
}
3. 代码读取三种方式
方式1:直接 IConfiguration(原始读取)
ini
var conn = configuration["ConnectionStrings:Default"];
var apiUrl = configuration["App:ApiUrl"];
方式2:IOptions(最推荐,强类型绑定)
csharp
public class AppOptions
{
public string ApiUrl { get; set; }
public int MaxBatch { get; set; }
}
// Program.cs
builder.Services.Configure<AppOptions>(builder.Configuration.GetSection("App"));
IOptions<T>:启动一次性读取,不热更新IOptionsSnapshot<T>:请求级别,自动监听json变更(reloadOnChange:true)IOptionsMonitor<T>:单例,支持OnChange回调
4. reloadOnChange 开关
php
// 手动添加json文件,开启热加载
configuration.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
默认模板自带 true;生产容器部署很多人手动关闭,避免配置文件被意外篡改自动生效。
5. 支持的全部内置配置提供程序
- Json(appsettings)、Xml、Ini
- 环境变量 EnvironmentVariablesConfigurationProvider
- 命令行 CommandLineConfigurationProvider
- UserSecrets(开发机密)
- Azure KeyVault / Azure App Configuration
- 内存配置 InMemoryCollection
- 自定义Provider(数据库、Nacos、Apollo等配置中心)
6. 环境变量控制环境
ini
# Linux/macOS
export ASPNETCORE_ENVIRONMENT=Production
# Windows cmd
set ASPNETCORE_ENVIRONMENT=Development
不设置默认 = Production
7. UserSecrets(用户机密,开发专用)
目的:密码、密钥不提交到git,存在用户目录,不在项目内
sql
dotnet user-secrets init
dotnet user-secrets set "ConnectionStrings:Default" "xxx"
仅Development环境加载,生产自动跳过。
第三部分:完整对比 .NET Framework machine.config 体系
- .NET Framework:
machine.config(整机) → web.config/app.config → runtime节点机器全局污染风险大,32/64两份独立文件,修改影响全部程序 - .NET Core/.NET5+:
runtimeconfig.json(单应用CLR) + IConfiguration多源配置体系(appsettings)无全局机器配置,每个应用隔离,云原生友好> > 如果想要整机统一策略:只能使用 DOTNET_ 开头的系统环境变量(对本机所有dotnet程序生效,替代老machine.config全局runtime策略)
第四部分:高频坑点汇总
- ❌ 混淆两者:把GC、AppContext开关写进appsettings,读了无效!这类开关必须在 runtimeconfig.json / DOTNET_环境变量
- ❌ 容器部署时修改appsettings.json不生效:容器内文件是镜像内的,要挂载或者用环境变量注入
- ❌ rollForward策略错误:测试环境和生产运行时版本不一致,直接启动失败
- ❌ 层级分隔符:环境变量只能用
__,不能用: - ❌ UserSecrets在生产环境依赖它:生产不会加载UserSecrets,会报空
- ❌ runtimeconfig.template.json放错目录:必须和csproj同级,不然编译不会合并