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

使用System.Text.Json转换格式不一致的JSON 泛型Converter无法标注属性如何解决

问题核心原因

C#特性的参数必须为编译期常量,泛型参数T属于运行时动态确定的类型,所以无法直接在[JsonConverter]特性中构造typeof(InconsistentConverter<T>)实例。


最优解决方案

自定义JsonConverterAttribute子类,运行时动态构造对应泛型类型的转换器实例,不需要全局注册转换器,仅对标记的属性生效:

  1. 首先实现自定义转换器特性:
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class InconsistentConverterAttribute : JsonConverterAttribute
{
    public override JsonConverter? CreateConverter(Type typeToConvert)
    {
        // 运行时根据属性的实际类型构造对应泛型参数的转换器
        var converterGenericType = typeof(InconsistentConverter<>).MakeGenericType(typeToConvert);
        return (JsonConverter?)Activator.CreateInstance(converterGenericType);
    }
}
  1. 改造Result<T>类,直接标记自定义特性即可:
public class Result<T>
    where T : class
{
    [JsonPropertyName("data")]
    [InconsistentConverter]
    public T? Data { get; set; }

    [JsonPropertyName("errors")]
    [InconsistentConverter]
    public Error? Error { get; set; }
}

转换器逻辑优化建议

原转换器仅读取一次数组开头就返回,遇到非空数组时可能出现JSON解析错位,可调整为跳过整个数组结构:

internal class InconsistentConverter<T> : JsonConverter<T>
{
    public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (reader.TokenType == JsonTokenType.StartArray)
        {
            // 跳过整个数组结构,无论是否包含元素,避免后续字段解析错位
            while (reader.Read())
            {
                if (reader.TokenType == JsonTokenType.EndArray)
                    break;
            }
            return default;
        }
        return JsonSerializer.Deserialize<T>(ref reader, options);
    }

    public override void Write(Utf8JsonWriter writer, T objectToWrite, JsonSerializerOptions options)
    {
        throw new NotImplementedException();
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 17:24:04