【问题标题】:FluentValidation: Apply Rule for all property by default automaticallyFluentValidation:默认情况下自动为所有属性应用规则
【发布时间】:2019-03-15 05:41:26
【问题描述】:

我有一个类 Person 有一些属性,所以我想默认自动为所有属性应用 FluentValidation Rule

  • 示例:
    • string: NotNull(), NotEmpty(), Length()...
    • enum: IsInEnum()
    • List: NotNull() or something else...
    • ...

人物和扩展方法

public enum Gender { Male, Female }

public class Person
{
    public Gender Gender { get; set; }
    public string Name { get; set; }
    public List<string> Notes { get; set; }
}

public static class Extension
{
    public static Expression<Func<T, TProperty>> GenerateExpression<T, TProperty>(PropertyInfo propInfo)
    {
        ParameterExpression paramExp = Expression.Parameter(typeof(T));
        MemberExpression memExp = Expression.Property(paramExp, propInfo);
        UnaryExpression unaryExp = Expression.Convert(memExp, propInfo.PropertyType);
        return Expression.Lambda<Func<T, TProperty>>(unaryExp, paramExp);
    }
}

基础验证器

我使用Extension.GenerateExpression 基于列表属性构建Expression,然后将其传递给RuleFor(),但它仅适用于字符串类型。 我不知道如何处理其他数据类型。

public class BaseValidator<T> : AbstractValidator<T>
{
    public BaseValidator()
    {
        ParameterExpression paramExp = Expression.Parameter(typeof(T));

        foreach (PropertyInfo propInfo in typeof(T).GetProperties())
        {
            // String [WORKED]
            if (propInfo.PropertyType == typeof(string))
            {
                Expression<Func<T, string>> expression = Extension.GenerateExpression<T, string>(propInfo);
                RuleFor(expression).Length(1, 10); //.Matches("pattern");
            }

            // List [NOT WORK]
            else if (propInfo.PropertyType.IsGenericType)
            {
                Expression<Func<T, object>> expression = Extension.GenerateExpression<T, object>(propInfo);
                RuleFor(expression).NotNull(); //ItemsInRange(1, 2);
            }

            // Enum [EXCEPTION]
            else if (propInfo.PropertyType.IsEnum)
            {
                Expression<Func<T, Enum>> expression = Extension.GenerateExpression<T, Enum>(propInfo);
                // Expression of type 'Gender' cannot be used for return type 'System.Enum''
                RuleFor(expression).IsInEnum();
            }

            // Other type [How to handle?]
            else
            {
                //Expression<Func<T, ???>> expression = GenerateExpression<T, ???>(propInfo);
            }
        }
    }
}

人员验证器

public class PersonValidator : BaseValidator<Person> { }

计划

public class Program
{
    public static void Main(string[] args)
    {
        Person person = new Person
        {
            Name = "Name",
            Gender = Gender.Male,
            Notes = new List<string> { "Note 1", "Note 2" }
        };

        PersonValidator validation = new PersonValidator();
        ValidationResult result = validation.Validate(person);

        foreach (var error in result.Errors)
        {
            Console.WriteLine(error);
        }

        Console.ReadKey();
    }
}

【问题讨论】:

    标签: c# reflection fluentvalidation


    【解决方案1】:

    你可以试试这个:

    UnaryExpression unaryExp = Expression.Convert(memExp, typeof(TProperty));
    

    代替:

    UnaryExpression unaryExp = Expression.Convert(memExp, propInfo.PropertyType);
    

    它应该有助于泛型属性,但恐怕它对枚举没有帮助。 IsInEnum 方法必须知道枚举属性的真实类型,而不仅仅是 Enum

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-30
      • 1970-01-01
      • 1970-01-01
      • 2015-10-07
      • 2012-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多