🌶 perf(Validation): 规范校验特性设计,统一使用[Required]校验必填,禁止特性多引用

This commit is contained in:
喵你个汪呀 2025-08-17 12:49:53 +08:00
parent 8a339f008f
commit 75e5b8a06b
5 changed files with 39 additions and 24 deletions

View File

@ -26,11 +26,13 @@ public class DictAttribute : ValidationAttribute, ITransient
/// <summary>
/// 是否允许空字符串
/// </summary>
[Obsolete("参数已废弃,逻辑已删除,请使用[Required]")]
public bool AllowEmptyStrings { get; set; } = false;
/// <summary>
/// 允许空值,有值才验证,默认 false
/// </summary>
[Obsolete("参数已废弃,逻辑已删除,请使用[Required]")]
public bool AllowNullValue { get; set; } = false;
/// <summary>

View File

@ -10,7 +10,7 @@ namespace Admin.NET.Core;
/// 枚举值合规性校验特性
/// </summary>
[SuppressSniffer]
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Enum | AttributeTargets.Field, AllowMultiple = true)]
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Enum | AttributeTargets.Field)]
public class EnumAttribute : ValidationAttribute, ITransient
{
/// <summary>
@ -31,22 +31,22 @@ public class EnumAttribute : ValidationAttribute, ITransient
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
// 获取属性的类型
var property = validationContext.ObjectType.GetProperty(validationContext.MemberName);
if (property == null)
return new ValidationResult($"未知属性: {validationContext.MemberName}");
var property = validationContext.ObjectType.GetProperty(validationContext.MemberName!);
if (property == null) return new ValidationResult($"未知属性: {validationContext.MemberName}");
var propertyType = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType;
// 如果是可空类型则允许为null
var propertyType = Nullable.GetUnderlyingType(property.PropertyType);
if (value == null && propertyType == null) return ValidationResult.Success;
// 检查属性类型是否为枚举或可空枚举类型
// 获取实际属性类型
propertyType ??= property.PropertyType;
// 检查属性类型是否为枚举
if (!propertyType.IsEnum)
return new ValidationResult($"属性类型'{validationContext.MemberName}'不是有效的枚举类型!");
// 检查枚举值是否有效
if (value == null && Nullable.GetUnderlyingType(property.PropertyType) == null)
return new ValidationResult($"提示:{ErrorMessage}|枚举值不能为 null");
return new ValidationResult($"'{validationContext.MemberName}'不是有效的枚举类型!");
if (value != null && !Enum.IsDefined(propertyType, value))
return new ValidationResult($"提示:{ErrorMessage}|枚举值【{value}】不是有效的【{propertyType.Name}】枚举类型值!");
return new ValidationResult(ErrorMessage ?? $"'{value}'不是有效的'{validationContext.MemberName}'枚举值");
return ValidationResult.Success;
}

View File

@ -10,31 +10,44 @@ namespace Admin.NET.Core;
/// 身份证号码合规性校验特性
/// </summary>
[SuppressSniffer]
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true, Inherited = true)]
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class IdCardNoAttribute : ValidationAttribute
{
/// <summary>
/// 是否允许空字符串
/// </summary>
private bool AllowEmptyStrings { get; set; } = false;
[Obsolete("参数已废弃,逻辑已删除,请使用[Required]")]
public bool AllowEmptyStrings { get; set; } = false;
/// <summary>
/// 允许空值,有值才验证,默认 false
/// </summary>
private bool AllowNullValue { get; set; } = false;
[Obsolete("参数已废弃,逻辑已删除,请使用[Required]")]
public bool AllowNullValue { get; set; } = false;
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
// 判断是否允许空值
if (AllowNullValue && value == null) return ValidationResult.Success;
if (IsEmpty(value)) return ValidationResult.Success;
string idCardNo = value?.ToString();
// 是否允许空字符串
if (AllowEmptyStrings && string.IsNullOrEmpty(idCardNo)) return ValidationResult.Success;
if (!IdCardHelper.CheckIdCard(idCardNo)) return new ValidationResult($"身份证号码({idCardNo})校验未通过, 请检查证件号的有效性!");
if (!IdCardHelper.CheckIdCard(idCardNo))
return new ValidationResult($"身份证号格式不正确");
return ValidationResult.Success;
}
/// <summary>
/// 判断值是否为空null、空字符串、空集合
/// </summary>
private static bool IsEmpty(object? value)
{
return value switch
{
null => true,
string s => string.IsNullOrWhiteSpace(s),
IList list => list.Count == 0,
_ => false
};
}
}

View File

@ -35,7 +35,7 @@ public class AddOrgInput : SysOrg
/// <summary>
/// 机构类型
/// </summary>
[Dict("org_type", ErrorMessage = "机构类型不能合法", AllowNullValue = true, AllowEmptyStrings = true)]
[Dict("org_type", ErrorMessage = "机构类型不能合法")]
public override string? Type { get; set; }
}

View File

@ -80,13 +80,13 @@ public class PageSerialInput : BasePageInput
/// <summary>
/// 使用分类
/// </summary>
[Dict(nameof(SerialTypeEnum), AllowNullValue = true)]
[Dict(nameof(SerialTypeEnum))]
public SerialTypeEnum? Type { get; set; }
/// <summary>
/// 状态
/// </summary>
[Dict(nameof(StatusEnum), AllowNullValue = true)]
[Dict(nameof(StatusEnum))]
public StatusEnum? Status { get; set; }
}