runtimeconfig.json + appsettings 完整详解(.NET Core/.NET5+,对比 machine.config)

9 阅读5分钟

一句话分界:

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.jsonappsettings.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控制开关:

<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>

SDK项目默认true,大部分场景不用动。

2. 完整标准模板

{
  "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
    }
  }
}

节点解释

  1. tfm:Target Framework Moniker,目标框架,如 net6.0 / net7.0 / net8.0
  2. 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 清单

"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 优先级(由低→高,后者覆盖前者)

  1. runtimeconfig.json / template.json
  2. csproj 里 MSBuild 属性(<RuntimeConfigProperty>)
  3. 环境变量(DOTNET_ 前缀, .NET9开始环境变量优先级最高)
  4. 代码 AppContext.SetSwitch()(进程内,代码启动后)

⚠️ 没有机器全局runtimeconfig!想整机统一GC策略:只能靠系统环境变量 DOTNET_ *,对本机所有dotnet程序生效。

4. 程序集绑定(对应Framework assemblyBinding)

.NET Core 不再使用xml bindingRedirect,分两种模式:

  1. 依赖项版本自动选择(默认) :NuGet解析、运行时按依赖图自动选版本
  2. 手动版本重定向:在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的相同键

  1. appsettings.json(基础公共配置)
  2. appsettings.{Environment}.json(环境差异化,例如 appsettings.Production.json / appsettings.Development.json)
  3. 用户机密 UserSecrets(仅 Development 环境,开发本地密钥,不提交git)
  4. 环境变量
  5. 命令行参数 args(最高优先级,运维临时覆盖)

环境变量名称规则:__ 双下划线替代层级冒号 : 例:ConnectionStrings__Default 等价于 Configuration["ConnectionStrings:Default"]

2. 文件示例 appsettings.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(开发环境,覆盖上面)

{
  "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(原始读取)

var conn = configuration["ConnectionStrings:Default"];
var apiUrl = configuration["App:ApiUrl"];

方式2:IOptions(最推荐,强类型绑定)

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 开关

// 手动添加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. 环境变量控制环境

# Linux/macOS
export ASPNETCORE_ENVIRONMENT=Production
# Windows cmd
set ASPNETCORE_ENVIRONMENT=Development

不设置默认 = Production

7. UserSecrets(用户机密,开发专用)

目的:密码、密钥不提交到git,存在用户目录,不在项目内

dotnet user-secrets init
dotnet user-secrets set "ConnectionStrings:Default" "xxx"

仅Development环境加载,生产自动跳过。

第三部分:完整对比 .NET Framework machine.config 体系

  1. .NET Framework: machine.config(整机) → web.config/app.config → runtime节点机器全局污染风险大,32/64两份独立文件,修改影响全部程序
  2. .NET Core/.NET5+: runtimeconfig.json(单应用CLR) + IConfiguration多源配置体系(appsettings)无全局机器配置,每个应用隔离,云原生友好> > 如果想要整机统一策略:只能使用 DOTNET_ 开头的系统环境变量(对本机所有dotnet程序生效,替代老machine.config全局runtime策略)

第四部分:高频坑点汇总

  1. ❌ 混淆两者:把GC、AppContext开关写进appsettings,读了无效!这类开关必须在 runtimeconfig.json / DOTNET_环境变量
  2. ❌ 容器部署时修改appsettings.json不生效:容器内文件是镜像内的,要挂载或者用环境变量注入
  3. ❌ rollForward策略错误:测试环境和生产运行时版本不一致,直接启动失败
  4. ❌ 层级分隔符:环境变量只能用 __,不能用 :
  5. ❌ UserSecrets在生产环境依赖它:生产不会加载UserSecrets,会报空
  6. ❌ runtimeconfig.template.json放错目录:必须和csproj同级,不然编译不会合并