You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Microsoft.Extensions.Configuration反序列化JSON配置的多类型派生类集合

问题根因

Microsoft.Extensions.Configuration 默认的配置绑定逻辑不支持多态类型反序列化,当你声明的集合元素类型是抽象基类Notifier时,绑定器会尝试直接实例化Notifier,自然无法成功,也不会自动识别你要实例化的是哪个子类。

解决方案

方案1:手动遍历配置段绑定(无额外依赖,推荐)

首先放开JSON配置里注释的type字段,明确标记每个通知器的实现类型:

{
  "NotifierConfig": {
    "Notifiers": [
      {
        "type": "MailNotifier",
        "Name": "MailNotifier_Admin",
        "MailAddress": "admin@somecompany.com"
      },
      {
        "type": "MailNotifier",
        "Name": "MailNotifier_CEO",
        "MailAddress": "ceo@somecompany.com"
      },
      {
        "type": "SmsNotifier",
        "Name": "SmsNotifier_Admin",
        "PhoneNumber": "1234567"
      },
      {
        "type": "SmsNotifier",
        "Name": "SmsNotifier_CEO",
        "PhoneNumber": "7654321"
      }
    ]
  }
}

然后手动遍历配置段,根据type字段实例化对应子类,再绑定配置:

NotifierConfig notifierConfig = new NotifierConfig
{
    Notifiers = new List<Notifier>()
};
// 读取Notifiers集合的配置段
IConfigurationSection notifiersSection = configuration.GetSection("NotifierConfig:Notifiers");
foreach (IConfigurationSection childSection in notifiersSection.GetChildren())
{
    // 读取类型标识
    string notifierType = childSection.GetValue<string>("type");
    Notifier instance = notifierType switch
    {
        "MailNotifier" => new MailNotifier(),
        "SmsNotifier" => new SmsNotifier(),
        _ => throw new NotSupportedException($"未定义的通知器类型:{notifierType}")
    };
    // 将当前配置段的属性绑定到实例上
    childSection.Bind(instance);
    notifierConfig.Notifiers.Add(instance);
}

方案2:借助Newtonsoft.Json实现多态反序列化

如果你更习惯用Newtonsoft.Json的TypeNameHandling能力,可以先把配置段转成JSON再反序列化,无需手动写匹配逻辑:

  1. 先安装Newtonsoft.Json NuGet包
  2. 代码实现:
using Newtonsoft.Json;

// 将配置段转换为JSON字符串
string configJson = JsonConvert.SerializeObject(configuration.GetSection("NotifierConfig").Get<Dictionary<string, object>>());
// 反序列化时开启TypeNameHandling
NotifierConfig config = JsonConvert.DeserializeObject<NotifierConfig>(configJson, new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.Auto
});

注意如果用默认的TypeNameHandling.Auto,JSON里的类型字段需要改为"$type": "你的命名空间.MailNotifier, 程序集名称"的格式,也可以自定义JsonConverter识别你原来的短名type字段。

内容的提问来源于stack exchange,提问作者Ben

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 20:54:04