在Xamarin Forms中用Restsharp/Json.net反序列化多类型JSON对象
这个问题我之前在处理多态JSON反序列化时也踩过坑!核心原因是默认的JSON序列化器(不管是Newtonsoft.Json还是System.Text.Json)都不会自动识别子类类型——它只会按照你指定的BaseClass来创建实例,所以你后续强行转换为ClassA或ClassB自然会得到null。
解决的关键就是给序列化器配置多态识别规则,下面分两种常用的序列化器给你具体讲:
一、如果你用的是Newtonsoft.Json(Xamarin中常用)
方案1:自定义类型转换器(推荐,更安全可控)
你需要创建一个自定义转换器,让序列化器能根据JSON中的标识字段(比如每个对象里的Type字段)判断应该实例化哪个子类。
示例代码:
// 自定义转换器 public class BaseClassConverter : JsonConverter<BaseClass> { public override BaseClass ReadJson(JsonReader reader, Type objectType, BaseClass existingValue, bool hasExistingValue, JsonSerializer serializer) { var jsonObj = JObject.Load(reader); // 从JSON中读取类型标识,比如"Type"字段的值 var typeFlag = jsonObj["Type"]?.Value<string>(); return typeFlag switch { "ClassA" => jsonObj.ToObject<ClassA>(serializer), "ClassB" => jsonObj.ToObject<ClassB>(serializer), _ => throw new NotSupportedException($"无法识别的类型:{typeFlag}") }; } public override void WriteJson(JsonWriter writer, BaseClass value, JsonSerializer serializer) { // 序列化时自动带上类型标识(可选,根据需求调整) var jObj = JObject.FromObject(value); jObj.Add("Type", value.GetType().Name); jObj.WriteTo(writer); } } // 在基类上标记使用这个转换器 [JsonConverter(typeof(BaseClassConverter))] public class BaseClass { } // 子类示例 public class ClassA : BaseClass { public string UniquePropA { get; set; } } public class ClassB : BaseClass { public int UniquePropB { get; set; } }
之后反序列化时直接用常规方式即可:
var jsonStr = "你的JSON字符串"; var resultList = JsonConvert.DeserializeObject<List<BaseClass>>(jsonStr);
方案2:使用TypeNameHandling(适合内部系统,注意安全)
如果你的JSON是自己系统生成的,可以开启TypeNameHandling.Auto,让序列化器自动在JSON中添加类型信息,反序列化时自动识别:
var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto }; // 序列化时会自动加入$type字段 var serialized = JsonConvert.SerializeObject(yourList, settings); // 反序列化时就能自动识别子类 var deserialized = JsonConvert.DeserializeObject<List<BaseClass>>(serialized, settings);
⚠️ 注意:如果JSON来自外部不可信源,不要用这个方案,存在安全风险。
二、如果你用的是System.Text.Json(.NET Core/.NET 5+推荐)
可以直接用特性标记来配置多态规则,非常简洁:
// 在基类上标记多态配置 [JsonPolymorphic(TypeDiscriminatorPropertyName = "Type")] [JsonDerivedType(typeof(ClassA), typeDiscriminator: "ClassA")] [JsonDerivedType(typeof(ClassB), typeDiscriminator: "ClassB")] public class BaseClass { } // 子类示例 public class ClassA : BaseClass { public string UniquePropA { get; set; } } public class ClassB : BaseClass { public int UniquePropB { get; set; } }
反序列化时直接调用即可,序列化器会自动根据Type字段识别子类:
var jsonStr = "你的JSON字符串"; var resultList = JsonSerializer.Deserialize<List<BaseClass>>(jsonStr);
关键注意点
- 确保你的JSON中存在能区分子类的标识字段(比如
Type),如果是外部API返回的JSON没有这个字段,你可能需要根据子类独有的属性来判断(比如检查JSON中是否存在UniquePropA来识别ClassA)。 - 不管用哪种方案,都要保证子类的属性和JSON字段能正确映射(比如名称一致,或者用
JsonProperty特性指定映射关系)。
内容的提问来源于stack exchange,提问作者bit
相关产品推荐
相关产品推荐

