JsonConvert反序列化枚举默认取首个值的问题排查与修复咨询
问题原因及修复方案
原因分析
问题根源在于Newtonsoft.Json(JsonConvert所属库)的构造函数选择逻辑,以及枚举反序列化的配置细节:
- Newtonsoft.Json默认优先选择带参构造函数实例化对象,即便你添加了无参构造,只要类存在带参构造,序列化器仍会尝试用带参构造创建实例。
- 如果带参构造的参数名称与JSON中的字段名不匹配(比如JSON字段是
type,构造参数是typeEnum),或者构造函数未正确处理枚举参数的赋值,typeEnum字段会被赋予枚举的默认值(枚举默认值为0,对应你定义的第一个枚举项WARNING),而非JSON中的ERROR。 - 若枚举未配置字符串转枚举的转换器,JSON中的字符串值也无法被正确解析为对应枚举项,最终 fallback 到默认值。
修复方法
方法1:强制序列化器使用无参构造
在Message类的无参构造上添加[JsonConstructor]特性,明确指定序列化器优先使用该构造函数:
public class Message { [JsonConstructor] public Message() { } public Message(MessageType typeEnum, string content) { TypeEnum = typeEnum; Content = content; } public MessageType TypeEnum { get; set; } public string Content { get; set; } }
方法2:修正带参构造的参数映射
若需保留带参构造的使用,确保构造参数与JSON字段名匹配,或通过[JsonProperty]指定映射关系:
public class Message { public Message([JsonProperty("type")] MessageType typeEnum, string content) { TypeEnum = typeEnum; Content = content; } public Message() { } public MessageType TypeEnum { get; set; } public string Content { get; set; } }
方法3:配置枚举的字符串转换器
给枚举类型添加[JsonConverter(typeof(StringEnumConverter))]特性,确保JSON字符串能正确反序列化为枚举值:
[JsonConverter(typeof(StringEnumConverter))] public enum MessageType { WARNING, ERROR }
若枚举名称与JSON字符串大小写不匹配(比如JSON是error而枚举是ERROR),可配置转换器忽略大小写:
[JsonConverter(typeof(StringEnumConverter), true)] // true表示忽略大小写 public enum MessageType { WARNING, ERROR }
方法4:全局配置序列化器
若不想给每个类或枚举加特性,可全局配置JsonSerializerSettings:
var settings = new JsonSerializerSettings { ConstructorHandling = ConstructorHandling.DefaultConstructor, // 优先使用无参构造 Converters = { new StringEnumConverter(true) } // 全局启用字符串枚举转换并忽略大小写 }; var message = JsonConvert.DeserializeObject<Message>(jsonStr, settings);
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

