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

ASP.NET Core 3.1中如何编写仅自定义Read方法的System.Text.Json转换器?

解决System.Text.Json自定义转换器仅自定义反序列化的问题

你遇到的问题是因为在Write方法中直接调用JsonSerializer.Serialize时,会再次使用你注册的自定义转换器,导致序列化逻辑异常,最终输出了字符串形式的JSON对象而非正常的JSON结构。下面提供两种可行的解决方案:

方法一:在Write方法中使用移除当前转换器的新配置

修改你的Write方法,创建一个复制原有配置但移除当前自定义转换器的JsonSerializerOptions实例,再用这个新配置进行序列化,就能触发默认的序列化逻辑:

public class MyTypeConverter<T> : JsonConverter<T> where T : MyType<T> 
{ 
    public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) 
    { 
        // 执行你的自定义反序列化逻辑
        // 示例:假设MyType<T>有Key和Value属性,自定义读取逻辑
        using (var doc = JsonDocument.ParseValue(ref reader))
        {
            var root = doc.RootElement;
            var key = root.GetProperty("Key").GetInt32();
            var value = root.GetProperty("Value").GetString();
            // 假设MyType<T>有对应的构造函数
            return (T)Activator.CreateInstance(typeof(T), key, value);
        }
    } 

    public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) 
    { 
        // 创建新配置,复制原有设置并移除当前转换器
        var defaultOptions = new JsonSerializerOptions(options);
        defaultOptions.Converters.Remove(this);
        
        // 使用默认配置序列化,输出正常的JSON对象
        JsonSerializer.Serialize(writer, value, defaultOptions);
    } 
}

方法二:使用JsonConverterFactory支持所有MyType泛型类型(可选)

如果你需要让所有MyType<T>的泛型实例都自动应用这个转换器,可以创建一个JsonConverterFactory来批量处理,避免手动注册每个具体的泛型类型:

public class MyTypeConverterFactory : JsonConverterFactory
{
    public override bool CanConvert(Type typeToConvert)
    {
        // 判断当前类型是否是MyType<>的泛型实例
        return typeToConvert.IsGenericType && 
               typeToConvert.GetGenericTypeDefinition() == typeof(MyType<>);
    }

    public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
    {
        // 获取泛型参数T
        Type genericArg = typeToConvert.GetGenericArguments()[0];
        // 创建对应的MyTypeConverter<T>实例
        Type converterType = typeof(MyTypeConverter<>).MakeGenericType(genericArg);
        return (JsonConverter)Activator.CreateInstance(converterType);
    }
}

然后在Startup.cs中注册这个工厂:

services.AddControllers()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.Converters.Add(new MyTypeConverterFactory());
    });

注意事项

  • 你原来代码里Write方法的参数TEnum是笔误,要改成T才能匹配泛型转换器的类型。
  • 复制JsonSerializerOptions是浅复制,对于大部分常规配置场景已经足够;如果你的配置中有复杂自定义转换器或特殊设置,需要确保复制逻辑能覆盖你的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:25:28