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

System.Text.Json序列化NotSupportedException问题求助

解决System.Text.Json序列化EventStoreDb对象时的MethodBase不支持错误

问题原因

错误提示中的TargetSite是Exception类的内置属性,类型为System.Reflection.MethodBase——System.Text.Json默认不支持序列化/反序列化这个类型。大概率是你的MessageClass、BaseClass或子类中直接或间接包含了Exception类型的属性,序列化时被自动遍历到TargetSite字段,导致报错。另外,你使用抽象类BaseClass作为EventData的属性类型,若未配置多态序列化支持,也可能引发额外的序列化异常。

解决方案

1. 检查并处理类中的Exception属性

  • 遍历MessageClass、BaseClass及所有子类,确认是否存在Exception类型的属性(比如public Exception Error { get; set; })。
  • 如果不需要序列化该属性,直接添加[JsonIgnore]特性标记:
    public class MessageClass
    {
        // 忽略Exception属性,避免序列化TargetSite
        [JsonIgnore]
        public Exception Error { get; set; }
        // 其他属性...
    }
    
  • 如果需要保留Exception的关键信息(如Message、StackTrace),可以手动提取这些字段,替换原有的Exception属性:
    public class MessageClass
    {
        public string ErrorMessage { get; set; }
        public string ErrorStackTrace { get; set; }
        
        // 用方法转换Exception信息
        public void SetError(Exception ex)
        {
            ErrorMessage = ex.Message;
            ErrorStackTrace = ex.StackTrace;
        }
    }
    

2. 配置多态序列化支持

由于EventData是抽象类BaseClass类型,实际赋值为子类EventChild,必须告诉System.Text.Json如何识别子类类型:

  • 方式一:特性标记
    在抽象类BaseClass上添加[JsonDerivedType]特性,声明所有可能的子类:
    [JsonDerivedType(typeof(EventChild), typeDiscriminator: "EventChild")]
    // 如有其他子类,继续添加
    // [JsonDerivedType(typeof(AnotherEventChild), typeDiscriminator: "AnotherEventChild")]
    public abstract class BaseClass : MessageClass
    {
        // 类内容...
    }
    
  • 方式二:序列化选项配置
    创建JsonSerializerOptions时添加多态转换器:
    var jsonOptions = new JsonSerializerOptions
    {
        PropertyNameCaseInsensitive = true,
        Converters = { new JsonPolymorphicConverter<BaseClass>() }
    };
    

3. 统一序列化/反序列化配置

确保写入EventStoreDb和读取时使用完全相同的JsonSerializerOptions,否则反序列化会因类型识别失败或配置不一致报错:

  • 写入示例:
    var eventPayload = JsonSerializer.SerializeToUtf8Bytes(yourEventClassInstance, jsonOptions);
    var eventData = new EventData(
        Uuid.NewUuid(),
        typeof(EventChild).Name,
        eventPayload
    );
    await eventStore.AppendToStreamAsync("your-stream-name", StreamState.Any, eventData);
    
  • 读取示例:
    var streamResult = await eventStore.ReadStreamAsync(
        Direction.Forwards,
        "your-stream-name",
        StreamPosition.Start,
        maxCount: 100
    );
    
    foreach (var resolvedEvent in streamResult)
    {
        var eventClass = JsonSerializer.Deserialize<EventClass>(
            resolvedEvent.Event.Data.Span,
            jsonOptions
        );
        // 处理事件逻辑
    }
    

4. 自定义转换器处理Exception(可选)

如果无法修改类结构,必须保留Exception属性,可以自定义JsonConverter过滤掉不支持的TargetSite字段:

public class ExceptionJsonConverter : JsonConverter<Exception>
{
    public override Exception Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        // 反序列化时按需返回,示例返回null,也可手动构建Exception对象
        return null;
    }

    public override void Write(Utf8JsonWriter writer, Exception value, JsonSerializerOptions options)
    {
        // 只序列化Exception的必要字段,跳过TargetSite
        writer.WriteStartObject();
        writer.WriteString("Message", value.Message);
        writer.WriteString("StackTrace", value.StackTrace);
        writer.WriteString("Source", value.Source);
        writer.WriteEndObject();
    }
}

将转换器添加到序列化选项中:

jsonOptions.Converters.Add(new ExceptionJsonConverter());

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 11:01:29