如何创建泛型类映射属性名-消息集合与DTO以实现验证
泛型验证类实现方案
咱们可以通过泛型+反射的方式来实现这个需求,既灵活又能适配不同的DTO类。下面是完整的实现思路和代码示例:
1. 核心泛型验证类设计
首先创建一个GenericValidator<T>泛型类,它会持有你的Rule集合,并提供验证方法来检查DTO对象:
using System; using System.Collections.Generic; using System.Linq; using System.Reflection; // 保留你原有的Rule类不变 public class Rule { public string PropertyName { get; set; } public string Message { get; set; } } public class GenericValidator<T> where T : class, new() { private readonly IEnumerable<Rule> _validationRules; // 构造函数传入验证规则集合 public GenericValidator(IEnumerable<Rule> validationRules) { _validationRules = validationRules ?? throw new ArgumentNullException(nameof(validationRules)); } // 核心验证方法,返回所有验证失败的消息 public List<string> Validate(T dto) { var errorMessages = new List<string>(); if (dto == null) { errorMessages.Add("待验证的DTO对象不能为null"); return errorMessages; } // 通过反射获取DTO的所有公开实例属性 var dtoProperties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (var rule in _validationRules) { // 匹配规则中的属性名和DTO的属性(忽略大小写,也可以改成严格匹配) var targetProperty = dtoProperties.FirstOrDefault(p => p.Name.Equals(rule.PropertyName, StringComparison.OrdinalIgnoreCase)); if (targetProperty == null) { // 如果Rule里的属性名在DTO中不存在,可选择忽略或添加提示 errorMessages.Add($"DTO中未找到属性: {rule.PropertyName}"); continue; } // 获取属性值,检查是否为空(这里处理必填验证,后续可扩展其他规则) var propertyValue = targetProperty.GetValue(dto)?.ToString(); if (string.IsNullOrWhiteSpace(propertyValue)) { errorMessages.Add(rule.Message); } } return errorMessages; } }
2. 使用示例(针对你的Client类)
现在咱们用Client类来测试这个泛型验证器:
// 你的Client DTO类 public class Client { public string ClientId { get; set; } public string ClientName { get; set; } // 其他属性... } public class Program { public static void Main() { // 初始化验证规则集合 var validationRules = new List<Rule> { new Rule { PropertyName = "ClientId", Message = "Client Id is mandatory" }, new Rule { PropertyName = "ClientName", Message = "Client Name is mandatory" } }; // 创建针对Client类的验证器实例 var clientValidator = new GenericValidator<Client>(validationRules); // 测试一个缺少必填属性的Client对象 var invalidClient = new Client { ClientId = "", ClientName = null }; var errors = clientValidator.Validate(invalidClient); // 输出验证错误 foreach (var error in errors) { Console.WriteLine(error); } // 输出结果: // Client Id is mandatory // Client Name is mandatory } }
3. 可扩展点
这个基础实现可以轻松扩展:
- 支持更多验证规则(比如长度限制、格式验证等),可以给Rule类添加
ValidationType和ValidationParam字段 - 自定义验证结果类型(比如包含属性名和消息的对象,而不仅仅是字符串列表)
- 缓存反射获取的属性信息,提升频繁验证大量对象时的性能
内容的提问来源于stack exchange,提问作者Manoj kumar Singh




