使用DefaultBuilder注册合法JSON后CommandList对象为NULL的问题排查
问题描述
我有如下JSON配置:
{ "Command": [ { "start": { "name": "Get Connected", "duration": 208 } }, { "stop": { "name": "Get Connected", "duration": 208 } } ] }
使用以下代码注册并解析时,commandList始终为NULL:
services.Configure<CommandList>(configuration.GetSection("Command")); var commandList = configuration.GetSection("Command").Get<CommandList>();
对应的实体类定义:
public class CommandList { [JsonPropertyName("command")] public List<Command> Command { get; set; } } public class Command { [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("start")] public Attributes Start { get; set; } [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("stop")] public Attributes Stop { get; set; } } public class Attributes { [JsonPropertyName("name")] public string Name { get; set; } [JsonPropertyName("duration")] public long Duration { get; set; } }
最终希望将配置注入到CommandService中,但始终无法成功:
public CommandService(ILogger<CommandService> logger, IOptions<CommandList> options)
其他JSON结构可正常解析,想知道问题出在哪,以及当前JSON是否符合需求。
问题原因与修复方案
1. 配置绑定层级不匹配
你调用configuration.GetSection("Command")获取的是JSON中的数组节点,但CommandList类的结构是一个包含command属性的对象,两者结构完全不兼容,导致解析失败返回NULL。
2. 属性名称大小写不匹配
CommandList类中Command属性标注的[JsonPropertyName("command")]是小写,但JSON根节点的属性是大写的Command,默认配置绑定区分大小写,这进一步加剧了匹配失败的问题。
修复步骤(两种可选方案)
方案一:简化配置类型(推荐)
直接用List<Command>作为配置绑定的类型,无需CommandList包装类:
// 注册配置 services.Configure<List<Command>>(configuration.GetSection("Command")); // 修改CommandService构造函数 public CommandService(ILogger<CommandService> logger, IOptions<List<Command>> options)
方案二:调整实体类与绑定逻辑
如果要保留CommandList类,需要同步调整实体类和绑定代码:
- 修改
CommandList的属性名称匹配JSON:
public class CommandList { [JsonPropertyName("Command")] // 改为大写匹配JSON public List<Command> Command { get; set; } }
- 绑定的时候获取根配置节点,而非
Command子节点:
services.Configure<CommandList>(configuration); var commandList = configuration.Get<CommandList>();
JSON结构合理性说明
当前JSON结构是合法的,是否符合需求取决于你的业务场景:
- 如果业务需要一组独立的命令对象(每个对象要么是
start要么是stop),这个结构完全合理。 - 如果业务要求每个命令对象同时包含
start和stop属性,那当前结构不符合,需要调整为每个数组元素同时包含两个属性,例如:
{ "Command": [ { "start": { "name": "Get Connected", "duration": 208 }, "stop": { "name": "Get Connected", "duration": 208 } } ] }
内容的提问来源于stack exchange,提问作者Phil Davies
相关产品推荐
相关产品推荐

