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
相关产品推荐
相关产品推荐

