修改绑定模型逻辑
continuous-integration/drone/push Build is passing Details

Test_IRC_Net8
hang 2026-01-19 14:25:59 +08:00
parent 59ba1a6193
commit 473d10533a
2 changed files with 48 additions and 15 deletions

View File

@ -97,7 +97,7 @@ builder.Services.AddJsonLocalization(options => options.ResourcesPath = "Resourc
builder.Services.AddControllers(options =>
{
// 插到最前,抢在默认绑定器之前
options.ModelBinderProviders.Insert(0, new NullableStructModelBinderProvider());
//options.ModelBinderProviders.Insert(0, new NullableStructModelBinderProvider());
options.Filters.Add<ModelActionFilter>();
options.Filters.Add<ProjectExceptionFilter>();

View File

@ -38,30 +38,38 @@ public class NullableStructModelBinderProvider : IModelBinderProvider
// 获取要绑定的模型类型,比如 Guid?, int?, DateTime? 等
var type = context.Metadata.ModelType;
//创建默认的模型绑定器(系统的原逻辑)
var fallback = context.CreateBinder(context.Metadata);
// 1. 处理 string 类型
if (type == typeof(string))
{
return new StringNotNullableModelBinder(fallback);
}
// 检查是否是 Nullable<T> 类型
// 1. 必须是泛型类型
// 2. 泛型定义必须是 Nullable<>
if (!type.IsGenericType ||
type.GetGenericTypeDefinition() != typeof(Nullable<>))
return null; // 返回 null 表示"我不处理这个类型"
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
{
// 获取可空类型内部的实际类型,如 Guid?, int? 中的 Guid, int
var innerType = Nullable.GetUnderlyingType(type)!;
// 获取可空类型内部的实际类型,如 Guid?, int? 中的 Guid, int
var innerType = Nullable.GetUnderlyingType(type)!;
var binderType = typeof(NullableEmptyStringToNullBinder<>).MakeGenericType(innerType);
// 创建默认的模型绑定器(系统的原逻辑)
var fallback = context.CreateBinder(context.Metadata);
// 实例化绑定器,传入默认绑定器作为备用
return (IModelBinder)Activator.CreateInstance(binderType, fallback)!;
}
// 创建泛型绑定器类型NullableEmptyStringToNullBinder<T>
// 比如对于 Guid?,会创建 NullableEmptyStringToNullBinder<Guid>
var binderType = typeof(NullableEmptyStringToNullBinder<>).MakeGenericType(innerType);
// 实例化绑定器,传入默认绑定器作为备用
return (IModelBinder)Activator.CreateInstance(binderType, fallback)!;
return null; // 返回 null 表示"我不处理这个类型"
}
}
// 泛型约束T 必须是值类型struct这确保了只处理可空值类型
// 泛型约束T 必须是值类型struct这确保了只处理可空值类型 比如处理guid? 传递"" 为null
public class NullableEmptyStringToNullBinder<T> : IModelBinder where T : struct
{
private readonly IModelBinder _fallbackBinder;
@ -92,3 +100,28 @@ public class NullableEmptyStringToNullBinder<T> : IModelBinder where T : struct
await _fallbackBinder.BindModelAsync(context);
}
}
// 处理 string 的绑定器 如果前端不传递 或者null 时 处理为 ""
public class StringNotNullableModelBinder : IModelBinder
{
private readonly IModelBinder _fallbackBinder;
public StringNotNullableModelBinder(IModelBinder fallbackBinder)
{
_fallbackBinder = fallbackBinder;
}
public async Task BindModelAsync(ModelBindingContext context)
{
var value = context.ValueProvider.GetValue(context.ModelName).FirstValue;
// 前端不传或传空字符串,都设为 string.Empty
if (string.IsNullOrWhiteSpace(value))
{
context.Result = ModelBindingResult.Success(string.Empty);
return;
}
await _fallbackBinder.BindModelAsync(context);
}
}