如何实现List属性反序列化时:无传入值用默认枚举集合,有值则用传入值?
解决Newtonsoft.Json反序列化时列表属性默认值不被传入值覆盖的问题
问题原因
Newtonsoft.Json默认的ObjectCreationHandling行为是复用已存在的引用类型实例(比如你初始化的List<SiteEnum>)。当反序列化时,它会将JSON中的元素追加到现有列表中,而非替换整个列表。如果传入的枚举字符串无法匹配SiteEnum的成员,反序列化会跳过无效值,最终保留默认的全量枚举列表。
解决方案
方案1:修改反序列化设置,强制替换列表实例
在反序列化时指定ObjectCreationHandling.Replace,让JSON中的sites字段直接替换默认初始化的列表;若请求体未传递sites,则保留默认的全量枚举列表。
// 配置反序列化参数 var serializerSettings = new JsonSerializerSettings { ObjectCreationHandling = ObjectCreationHandling.Replace, // 添加字符串枚举转换器,确保字符串枚举能正确反序列化 Converters = new List<JsonConverter> { new StringEnumConverter() } }; // 执行反序列化 var request = JsonConvert.DeserializeObject<Request>(requestBody, serializerSettings);
方案2:调整类的初始化逻辑(可选)
将默认值初始化从属性定义移到构造函数中,配合方案1的设置,能更清晰地控制默认值逻辑:
public class Request { public List<SiteEnum> Sites { get; set; } public ReportTypeEnum ReportType { get; set; } = ReportTypeEnum.Daily; public DateTime ReportDate { get; set; } = DateTime.Now; public Request() { // 构造函数中初始化默认全量枚举列表 Sites = Enum.GetValues(typeof(SiteEnum)).Cast<SiteEnum>().ToList(); } }
额外注意事项
- 确保请求体中的
sites字符串与SiteEnum成员名称匹配,若需忽略大小写,可修改转换器设置:new StringEnumConverter { IgnoreCase = true } - 若请求体传入空
sites数组,反序列化后Sites会是空列表,这符合“传入时使用传入值”的需求。
内容的提问来源于stack exchange,提问作者Sonal Khatri
相关产品推荐
相关产品推荐

