使用System.Text.Json转换格式不一致的JSON 泛型Converter无法标注属性如何解决
问题核心原因
C#特性的参数必须为编译期常量,泛型参数T属于运行时动态确定的类型,所以无法直接在[JsonConverter]特性中构造typeof(InconsistentConverter<T>)实例。
最优解决方案
自定义JsonConverterAttribute子类,运行时动态构造对应泛型类型的转换器实例,不需要全局注册转换器,仅对标记的属性生效:
- 首先实现自定义转换器特性:
[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); } }
- 改造
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
相关产品推荐
相关产品推荐

