REST控制器动态移除IEnumerable<T>默认对象及JsonConverter转换问题
解决方案
1. 实现通用空对象判断方法
先写一个工具方法,用来判断对象的所有字符串属性是否全为空或空白:
public static class ObjectExtensions { public static bool IsAllStringPropertiesEmpty<T>(this T obj) { if (obj == null) return true; var stringProperties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance) .Where(p => p.PropertyType == typeof(string)); foreach (var prop in stringProperties) { var value = (string)prop.GetValue(obj); if (!string.IsNullOrWhiteSpace(value)) { return false; } } return true; } }
2. 实现泛型Enumerable转换器
创建泛型Json转换器,在反序列化时自动过滤掉符合条件的空对象:
public class EmptyObjectFilteringEnumerableConverter<T> : JsonConverter<IEnumerable<T>> { public override IEnumerable<T> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { // 先完成基础反序列化 var items = JsonSerializer.Deserialize<List<T>>(ref reader, options); // 过滤掉所有字符串属性全为空的对象 return items?.Where(item => !item.IsAllStringPropertiesEmpty()).ToList() ?? Enumerable.Empty<T>(); } public override void Write(Utf8JsonWriter writer, IEnumerable<T> value, JsonSerializerOptions options) { // 序列化逻辑沿用默认实现 JsonSerializer.Serialize(writer, value, options); } }
3. 用转换器工厂实现全局复用
如果需要让所有IEnumerable<T>类型的列表都自动应用这个过滤逻辑,可创建转换器工厂:
public class EmptyObjectFilteringEnumerableConverterFactory : JsonConverterFactory { public override bool CanConvert(Type typeToConvert) { // 判断是否为泛型集合类型 if (!typeToConvert.IsGenericType) return false; var genericDef = typeToConvert.GetGenericTypeDefinition(); return genericDef == typeof(IEnumerable<>) || genericDef == typeof(List<>) || genericDef == typeof(ICollection<>); } public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) { // 获取集合的元素类型,创建对应泛型转换器实例 var elementType = typeToConvert.GetGenericArguments()[0]; var converterType = typeof(EmptyObjectFilteringEnumerableConverter<>).MakeGenericType(elementType); return (JsonConverter)Activator.CreateInstance(converterType); } }
4. 注册转换器
在Program.cs中注册转换器或工厂,实现全局生效:
builder.Services.AddControllers() .AddJsonOptions(options => { // 方式一:注册工厂,自动处理所有泛型集合 options.JsonSerializerOptions.Converters.Add(new EmptyObjectFilteringEnumerableConverterFactory()); // 方式二:仅针对特定类型注册(如果不需要全局生效) // options.JsonSerializerOptions.Converters.Add(new EmptyObjectFilteringEnumerableConverter<EntityFieldInsertRequest>()); });
关键说明
- 之前的类型转换错误,是因为注册了针对
object的转换器,导致反序列化结果为List<object>,无法转换为具体的IEnumerable<EntityFieldInsertRequest>。使用泛型工厂或针对具体元素类型注册转换器,可彻底解决这个问题。 - 工具方法仅检查字符串属性,完全匹配你需求中“移除列表中所有属性为空字符串的默认对象”的要求,若后续需要扩展判断逻辑,直接修改
IsAllStringPropertiesEmpty方法即可。
内容的提问来源于stack exchange,提问作者Ederson Leandro
相关产品推荐
相关产品推荐

