You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何创建泛型类映射属性名-消息集合与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类添加ValidationTypeValidationParam字段
  • 自定义验证结果类型(比如包含属性名和消息的对象,而不仅仅是字符串列表)
  • 缓存反射获取的属性信息,提升频繁验证大量对象时的性能

内容的提问来源于stack exchange,提问作者Manoj kumar Singh

火山引擎 最新活动