如何使用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再反序列化,无需手动写匹配逻辑:
- 先安装Newtonsoft.Json NuGet包
- 代码实现:
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
相关产品推荐
相关产品推荐

