.NET Core实现读取数据库正则的自定义ValidationAttribute方案咨询
解决方案
方法1:直接通过ValidationContext获取服务(推荐,适配DI规则)
.NET Core 验证流程自带的ValidationContext内置GetService()方法,可以直接读取DI容器中注册的服务,不需要额外向属性类注入依赖,修改你的属性代码如下即可:
public sealed class RegexPatternAttribute : ValidationAttribute { private readonly string _columnName; public RegexPatternAttribute(string columnName) { _columnName = columnName; } protected override ValidationResult IsValid(object value, ValidationContext validationContext) { // 空值跳过校验,必填校验可搭配[Required]属性使用 if (value == null) return ValidationResult.Success; string inputValue = value.ToString(); // 直接从ValidationContext获取已注册的IDataRepository var dataRepository = (IDataRepository)validationContext.GetService(typeof(IDataRepository)); var regexDict = dataRepository.LoadRegexPatterns(); if (!regexDict.TryGetValue(_columnName, out var regexPattern)) { return new ValidationResult($"未找到{_columnName}对应的校验规则"); } if (Regex.IsMatch(inputValue, regexPattern)) { return ValidationResult.Success; } else { return new ValidationResult(ErrorMessage ?? $"{_columnName}格式不符合规则"); } } }
你只需要正常在Startup.ConfigureServices中注册IDataRepository即可,不需要额外配置,验证时框架会自动将服务提供者传入ValidationContext。
方法2:预加载单例缓存字典(适合正则规则变动少的场景)
如果你的正则规则很少更新,可以在应用启动时预加载到全局缓存,避免每次校验都查询数据库,性能更高:
- 先给属性类增加静态缓存字段:
public sealed class RegexPatternAttribute : ValidationAttribute { // 全局静态缓存,应用生命周期内唯一 public static IReadOnlyDictionary<string, string> RegexPatternCache { get; set; } private readonly string _columnName; public RegexPatternAttribute(string columnName) { _columnName = columnName; } protected override ValidationResult IsValid(object value, ValidationContext validationContext) { if (value == null) return ValidationResult.Success; string inputValue = value.ToString(); if (!RegexPatternCache.TryGetValue(_columnName, out var regexPattern)) { return new ValidationResult($"未找到{_columnName}对应的校验规则"); } return Regex.IsMatch(inputValue, regexPattern) ? ValidationResult.Success : new ValidationResult(ErrorMessage ?? $"{_columnName}格式不符合规则"); } }
- 在
Startup.ConfigureServices中注册完IDataRepository后预加载缓存:
public void ConfigureServices(IServiceCollection services) { // 你的原有服务注册 services.AddScoped<IDataRepository, 你的IDataRepository实现类>(); // 预加载正则缓存 var tempProvider = services.BuildServiceProvider(); using var scope = tempProvider.CreateScope(); var repo = scope.ServiceProvider.GetRequiredService<IDataRepository>(); RegexPatternAttribute.RegexPatternCache = repo.LoadRegexPatterns(); // 其他原有配置 services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); }
如果后续需要更新正则规则,直接修改RegexPatternAttribute.RegexPatternCache的值即可,不需要重启应用。
内容的提问来源于stack exchange,提问作者Kamil Turowski
相关产品推荐
相关产品推荐

