.Net中使用CsvHelper时如何让属性的RegularExpressionAttribute校验生效
CsvHelper触发DataAnnotations正则校验的解决方案
校验不生效的原因
CsvHelper核心功能是CSV数据和实体类的映射转换,默认不会自动执行System.ComponentModel.DataAnnotations命名空间下的特性校验(包括RegularExpressionAttribute、RequiredAttribute等),仅会在类型转换失败时抛出异常。
解决方案
方案1:读取完成后批量校验
读取所有记录后,手动调用.NET内置的Validator工具执行数据注解校验,适合不需要实时终止读取的场景:
using System.ComponentModel.DataAnnotations; // 读取CSV记录 var records = csvReader.GetRecords<MyClass>().ToList(); var allErrors = new List<string>(); foreach (var record in records) { var validationResults = new List<ValidationResult>(); var validationContext = new ValidationContext(record); // 第四个参数必须设为true,才会校验所有属性的注解规则 bool isValid = Validator.TryValidateObject(record, validationContext, validationResults, validateAllProperties: true); if (!isValid) { allErrors.AddRange(validationResults.Select(v => $"属性[{string.Join(",", v.MemberNames)}]校验失败:{v.ErrorMessage}")); } } // 存在校验错误时处理逻辑 if (allErrors.Any()) { throw new InvalidOperationException($"数据校验失败:{Environment.NewLine}{string.Join(Environment.NewLine, allErrors)}"); }
方案2:读取过程中实时校验
通过CsvHelper的Reading事件在每行读取完成后立即校验,可以直接获取当前行号,方便定位错误数据:
using System.ComponentModel.DataAnnotations; csvReader.Reading += (sender, args) => { var record = args.Record as MyClass; var validationResults = new List<ValidationResult>(); var validationContext = new ValidationContext(record); if (!Validator.TryValidateObject(record, validationContext, validationResults, validateAllProperties: true)) { var errorMsg = string.Join(";", validationResults.Select(v => v.ErrorMessage)); // 抛出异常终止读取,也可以自定义收集错误后继续读取 throw new InvalidOperationException($"第{args.Row.Row}行数据校验失败:{errorMsg}"); } }; // 读取时会自动触发每行校验 var records = csvReader.GetRecords<MyClass>().ToList();
注意事项
- 若需校验
RequiredAttribute对空字符串的限制,需要将特性的AllowEmptyStrings属性设为false - 自定义校验特性只要继承自
ValidationAttribute,以上两种方案都可以自动识别校验
内容的提问来源于stack exchange,提问作者darkmatter
相关产品推荐
相关产品推荐

