如何根据TypeName字段反序列化SampleClass中派生自BaseClass的Data属性?
解决方案:根据TypeName字段反序列化派生类属性
默认情况下,Json.NET反序列化SampleClass时,无法自动识别Data属性对应的派生类类型,只会实例化基类BaseClass,导致派生类特有的属性无法被反序列化,最终Data看起来为空。你可以通过自定义Json转换器来实现根据TypeName字段指定的类型反序列化Data属性。
步骤1:实现自定义Json转换器
创建一个继承自JsonConverter的转换器类,在反序列化逻辑中读取TypeName并动态确定Data的类型:
public class SampleClassConverter : JsonConverter { public override bool CanConvert(Type objectType) { // 只处理SampleClass类型 return objectType == typeof(SampleClass); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { // 读取整个JSON对象 var jObject = JObject.Load(reader); // 实例化SampleClass并反序列化基础属性 var sample = new SampleClass(); serializer.Populate(jObject.CreateReader(), sample); // 获取TypeName字段的值 var typeName = jObject["TypeName"]?.ToString(); if (string.IsNullOrEmpty(typeName)) return sample; // 根据TypeName找到对应的派生类型(替换为你的实际命名空间) var dataType = Type.GetType($"YourNamespace.{typeName}"); if (dataType == null) return sample; // 反序列化Data属性为指定的派生类型 sample.Data = (BaseClass)jObject["Data"].ToObject(dataType, serializer); return sample; } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { // 序列化时使用默认逻辑即可 serializer.Serialize(writer, value); } }
注意:将代码中的YourNamespace替换为DataClass所在的实际命名空间。如果派生类在其他程序集,需要调整Type.GetType的参数,传入完整的程序集限定名。
步骤2:使用转换器进行反序列化
在反序列化时指定使用自定义转换器:
var settings = new JsonSerializerSettings(); settings.Converters.Add(new SampleClassConverter()); var backToObject = JsonConvert.DeserializeObject<SampleClass>(jsonString, settings);
这样反序列化后,backToObject.Data会被正确实例化为DataClass类型,其Name和Address属性也能正常读取。
额外说明
- 如果有多个派生类,只需要确保
TypeName的值和类名完全一致,转换器就能自动匹配对应的类型。 - 若要更严谨,可以维护一个类型映射字典(比如
Dictionary<string, Type>),避免通过字符串反射查找类型时出现错误。
内容的提问来源于stack exchange,提问作者Belenos
相关产品推荐
相关产品推荐

