修改绑定模型逻辑
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
59ba1a6193
commit
473d10533a
|
|
@ -97,7 +97,7 @@ builder.Services.AddJsonLocalization(options => options.ResourcesPath = "Resourc
|
||||||
builder.Services.AddControllers(options =>
|
builder.Services.AddControllers(options =>
|
||||||
{
|
{
|
||||||
// 插到最前,抢在默认绑定器之前
|
// 插到最前,抢在默认绑定器之前
|
||||||
options.ModelBinderProviders.Insert(0, new NullableStructModelBinderProvider());
|
//options.ModelBinderProviders.Insert(0, new NullableStructModelBinderProvider());
|
||||||
|
|
||||||
options.Filters.Add<ModelActionFilter>();
|
options.Filters.Add<ModelActionFilter>();
|
||||||
options.Filters.Add<ProjectExceptionFilter>();
|
options.Filters.Add<ProjectExceptionFilter>();
|
||||||
|
|
|
||||||
|
|
@ -38,30 +38,38 @@ public class NullableStructModelBinderProvider : IModelBinderProvider
|
||||||
// 获取要绑定的模型类型,比如 Guid?, int?, DateTime? 等
|
// 获取要绑定的模型类型,比如 Guid?, int?, DateTime? 等
|
||||||
var type = context.Metadata.ModelType;
|
var type = context.Metadata.ModelType;
|
||||||
|
|
||||||
|
//创建默认的模型绑定器(系统的原逻辑)
|
||||||
|
var fallback = context.CreateBinder(context.Metadata);
|
||||||
|
|
||||||
|
|
||||||
|
// 1. 处理 string 类型
|
||||||
|
if (type == typeof(string))
|
||||||
|
{
|
||||||
|
return new StringNotNullableModelBinder(fallback);
|
||||||
|
}
|
||||||
|
|
||||||
// 检查是否是 Nullable<T> 类型
|
// 检查是否是 Nullable<T> 类型
|
||||||
// 1. 必须是泛型类型
|
// 1. 必须是泛型类型
|
||||||
// 2. 泛型定义必须是 Nullable<>
|
// 2. 泛型定义必须是 Nullable<>
|
||||||
if (!type.IsGenericType ||
|
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
|
||||||
type.GetGenericTypeDefinition() != typeof(Nullable<>))
|
{
|
||||||
return null; // 返回 null 表示"我不处理这个类型"
|
// 获取可空类型内部的实际类型,如 Guid?, int? 中的 Guid, int
|
||||||
|
var innerType = Nullable.GetUnderlyingType(type)!;
|
||||||
|
|
||||||
|
|
||||||
// 获取可空类型内部的实际类型,如 Guid?, int? 中的 Guid, int
|
var binderType = typeof(NullableEmptyStringToNullBinder<>).MakeGenericType(innerType);
|
||||||
var innerType = Nullable.GetUnderlyingType(type)!;
|
|
||||||
|
|
||||||
// 创建默认的模型绑定器(系统的原逻辑)
|
// 实例化绑定器,传入默认绑定器作为备用
|
||||||
var fallback = context.CreateBinder(context.Metadata);
|
return (IModelBinder)Activator.CreateInstance(binderType, fallback)!;
|
||||||
|
}
|
||||||
|
|
||||||
// 创建泛型绑定器类型:NullableEmptyStringToNullBinder<T>
|
|
||||||
// 比如对于 Guid?,会创建 NullableEmptyStringToNullBinder<Guid>
|
|
||||||
var binderType = typeof(NullableEmptyStringToNullBinder<>).MakeGenericType(innerType);
|
|
||||||
|
|
||||||
// 实例化绑定器,传入默认绑定器作为备用
|
return null; // 返回 null 表示"我不处理这个类型"
|
||||||
return (IModelBinder)Activator.CreateInstance(binderType, fallback)!;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 泛型约束:T 必须是值类型(struct),这确保了只处理可空值类型
|
// 泛型约束:T 必须是值类型(struct),这确保了只处理可空值类型 比如处理guid? 传递"" 为null
|
||||||
public class NullableEmptyStringToNullBinder<T> : IModelBinder where T : struct
|
public class NullableEmptyStringToNullBinder<T> : IModelBinder where T : struct
|
||||||
{
|
{
|
||||||
private readonly IModelBinder _fallbackBinder;
|
private readonly IModelBinder _fallbackBinder;
|
||||||
|
|
@ -91,4 +99,29 @@ public class NullableEmptyStringToNullBinder<T> : IModelBinder where T : struct
|
||||||
// 比如将 "123" 转换为 int? 123,或将 GUID 字符串转换为 Guid?
|
// 比如将 "123" 转换为 int? 123,或将 GUID 字符串转换为 Guid?
|
||||||
await _fallbackBinder.BindModelAsync(context);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue