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

C#动态反序列化多类型JSON字段的技术问题求助

动态反序列化多结构Readings字段的解决方案

问题核心原因

你遇到的报错本质是:第一次反序列化List<NodeResponse>时,若Readings字段定义为object或其他固定类型,Newtonsoft.Json会自动将原始JSON结构(数组/对象)转换为对应CLR类型(比如JArray),后续再尝试将其反序列化为需要JSON对象的VoltageReadingsV1时,类型不匹配导致失败。

方案一:保留原始JSON结构后动态转换

1. 调整NodeResponse类定义

将Readings字段类型改为JToken(Newtonsoft.Json.Linq命名空间下的类型),确保第一次反序列化时完整保留原始JSON的结构信息:

public class NodeResponse
{
    public string Type { get; set; }
    public JToken Readings { get; set; }
    // 其他业务字段...
}

2. 基于Type字段动态反序列化

反序列化完列表后,根据每个节点的Type值,将JToken转换为对应目标类型:

// 第一步:反序列化得到节点列表
var nodeResponses = JsonConvert.DeserializeObject<List<NodeResponse>>(rawJson);

// 第二步:遍历处理每个节点
foreach (var node in nodeResponses)
{
    switch (node.Type)
    {
        case "VoltageV1":
            var voltageData = node.Readings.ToObject<VoltageReadingsV1>();
            // 处理电压读数逻辑
            break;
        case "CurrentV2":
            var currentData = node.Readings.ToObject<CurrentReadingsV2>();
            // 处理电流读数逻辑
            break;
        // 其他已整理的类型分支...
        default:
            // 未知类型的 fallback 逻辑
            break;
    }
}

方案二:自定义JsonConverter自动处理

如果不想手动写分支逻辑,可以自定义转换器,在第一次反序列化时直接完成类型匹配:

1. 定义读数类型的基接口

让所有Readings类型实现统一接口,方便后续类型约束:

public interface ILoggerReadings { }

public class VoltageReadingsV1 : ILoggerReadings
{
    // 电压读数的字段定义
}

public class CurrentReadingsV2 : ILoggerReadings
{
    // 电流读数的字段定义
}

2. 修改NodeResponse类

public class NodeResponse
{
    public string Type { get; set; }
    public ILoggerReadings Readings { get; set; }
    // 其他业务字段...
}

3. 实现自定义转换器

public class ReadingsTypeConverter : JsonConverter<ILoggerReadings>
{
    // 预定义类型映射表,对应你整理的所有类型
    private readonly Dictionary<string, Type> _typeMapping = new()
    {
        { "VoltageV1", typeof(VoltageReadingsV1) },
        { "CurrentV2", typeof(CurrentReadingsV2) }
        // 其他类型映射项...
    };

    public override ILoggerReadings ReadJson(JsonReader reader, Type objectType, ILoggerReadings existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        // 加载整个节点的JSON对象
        var jNode = JObject.Load(reader);
        var typeFlag = jNode["Type"]?.Value<string>();

        if (string.IsNullOrEmpty(typeFlag) || !_typeMapping.TryGetValue(typeFlag, out var targetType))
        {
            throw new JsonSerializationException($"Unsupported readings type: {typeFlag}");
        }

        // 反序列化Readings字段为目标类型
        return (ILoggerReadings)jNode["Readings"].ToObject(targetType, serializer);
    }

    public override void WriteJson(JsonWriter writer, ILoggerReadings value, JsonSerializer serializer)
    {
        // 如果需要序列化回JSON,在此实现对应逻辑
        serializer.Serialize(writer, value);
    }
}

4. 使用转换器完成反序列化

var serializerSettings = new JsonSerializerSettings
{
    Converters = new List<JsonConverter> { new ReadingsTypeConverter() }
};

var nodeResponses = JsonConvert.DeserializeObject<List<NodeResponse>>(rawJson, serializerSettings);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 01:50:22