You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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);

关键注意点

  1. 确保你的JSON中存在能区分子类的标识字段(比如Type),如果是外部API返回的JSON没有这个字段,你可能需要根据子类独有的属性来判断(比如检查JSON中是否存在UniquePropA来识别ClassA)。
  2. 不管用哪种方案,都要保证子类的属性和JSON字段能正确映射(比如名称一致,或者用JsonProperty特性指定映射关系)。

内容的提问来源于stack exchange,提问作者bit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:22:46