多态类型鉴别器反序列化时未转换为枚举的问题求解
解决多态序列化中鉴别器字符串未映射到枚举的问题
核心问题原因
JsonPolymorphic特性的类型鉴别器仅用于识别派生类,不会自动将鉴别器字符串转换为枚举值并赋值给Type属性,因此即便反序列化正确识别了对象类型,Type字段仍会使用枚举的默认值。
最优解决方案:派生类构造函数初始化枚举
利用派生类与枚举值的一一对应关系,在每个派生类的构造函数中直接传入对应的枚举值,通过基类构造函数初始化Type属性,无需依赖JSON数据中的额外字段,也不需要冗余字段或应用层转换。
步骤1:定义枚举类型
public enum PenaltyType { FixedPenalty, FixedRatePenalty, RelativePenalty }
步骤2:修改基类Penalty
将Type属性设为只读,通过构造函数传入枚举值初始化:
[JsonPolymorphic(TypeDiscriminatorPropertyName = "type")] [JsonDerivedType(typeof(FixedPenalty), typeDiscriminator: "fixedPenalty")] [JsonDerivedType(typeof(FixedRatePenalty), typeDiscriminator: "fixedRatePenalty")] [JsonDerivedType(typeof(RelativePenalty), typeDiscriminator: "relativePenalty")] public abstract class Penalty { public PenaltyType Type { get; } public string Description { get; set; } protected Penalty(PenaltyType type, string description) { Type = type; Description = description; } }
步骤3:实现派生类
每个派生类通过构造函数调用基类构造方法,传入对应的枚举值:
// FixedPenalty示例 public class FixedPenalty : Penalty { public decimal Amount { get; set; } [JsonConstructor] public FixedPenalty(string description, decimal amount) : base(PenaltyType.FixedPenalty, description) { Amount = amount; } } // RelativePenalty示例 public class RelativePenalty : Penalty { public double Rate { get; set; } public string Unit { get; set; } [JsonConstructor] public RelativePenalty(string description, double rate, string unit) : base(PenaltyType.RelativePenalty, description) { Rate = rate; Unit = unit; } }
效果说明
当反序列化你提供的JSON时:
{ "type": "relativePenalty", "description": "string", "rate": 10.9, "unit": "year" }
系统会正确识别为RelativePenalty类型,其构造函数会调用基类构造方法,将Type属性设置为PenaltyType.RelativePenalty,无需额外处理即可得到正确的枚举值。
这种方案既保持了模型的简洁性,又确保了枚举值与对象类型的一致性,完全避免了冗余字段或应用层转换的麻烦。
内容的提问来源于stack exchange,提问作者Artur Safiullin
相关产品推荐
相关产品推荐

