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

SignalR传输MyDataClass时System.Text.Json序列化反序列化异常问题

解决SignalR传输MyDataClass时的序列化无限循环与反序列化问题

问题根源分析

你遇到的序列化无限循环,本质是自定义JsonConverter在序列化MyDataClass时触发了递归调用:因为类上标记了[JsonConverter]特性,当转换器的Write方法里尝试序列化MyDataClass实例时,会再次触发这个转换器,陷入无限循环。

而反序列化时Value变成JsonElement,是因为System.Text.Json默认会把未知类型的object序列化为JsonElement,无法自动映射回你需要的具体类型。

修复方案:正确实现自定义JsonConverter

修改你的MyDataClassConverter,在序列化时手动处理属性避免递归;反序列化时利用Format属性解析Value到对应类型,同时保留类上的[JsonConverter]特性实现全局配置。

1. MyDataClass定义(保留特性)

[JsonConverter(typeof(MyDataClassConverter))]
public class MyDataClass
{
    public string Format { get; set; }
    public object Value { get; set; }
}

2. 正确的自定义转换器实现

public class MyDataClassConverter : JsonConverter<MyDataClass>
{
    public override MyDataClass Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        // 先将JSON读为JsonElement,再提取属性解析
        using var doc = JsonDocument.ParseValue(ref reader);
        var root = doc.RootElement;
        
        var format = root.GetProperty("Format").GetString();
        var valueJson = root.GetProperty("Value").ToString();
        
        // 用FormatHelper将字符串转为对应类型对象
        var value = FormatHelper.GetObjectValue(valueJson, format);
        
        return new MyDataClass
        {
            Format = format,
            Value = value
        };
    }

    public override void Write(Utf8JsonWriter writer, MyDataClass value, JsonSerializerOptions options)
    {
        // 手动序列化属性,避免触发转换器递归
        writer.WriteStartObject();
        writer.WriteString("Format", value.Format);
        
        // 根据Format获取对应类型,精准序列化Value
        var targetType = GetTypeFromFormat(value.Format);
        JsonSerializer.Serialize(writer, value.Value, targetType, options);
        
        writer.WriteEndObject();
    }

    // 辅助方法:根据Format字符串匹配对应的Type
    private Type GetTypeFromFormat(string format)
    {
        // 这里根据你的Format规则实现映射,示例如下:
        return format switch
        {
            "int" => typeof(int),
            "string" => typeof(string),
            "datetime" => typeof(DateTime),
            "bool" => typeof(bool),
            // 补充你需要的其他类型映射
            _ => typeof(object)
        };
    }
}

核心要点

  • 序列化防递归:Write方法不直接序列化MyDataClass实例,而是手动写入Format和Value属性,序列化Value时指定具体类型,绕开自身转换器的递归调用。
  • 反序列化精准解析:先将JSON读为JsonElement,提取Format后用FormatHelper把Value的JSON字符串转成对应类型对象,解决JsonElement无法直接转换的问题。

效果验证

现在给MyDataClass加上[JsonConverter]特性后,不管是序列化单个实例还是列表,都不会出现无限循环;反序列化时Value也能正确解析为对应类型,无需再单独在反序列化时指定转换器,实现简洁的全局配置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 02:57:34