自定义验证器 Custom Valdiators

有几种创建自定义可重用验证器的方法。 推荐的方法是利用断言验证器编写自定义验证功能,但是您也可以使用Custom方法来完全控制验证过程。

断言验证器 我们将设想一个场景,您希望创建一个可重复使用的验证器,以确保列表对象包含的项少于 10 项。

断言验证器 Predicate Validator

最简单的方式是我们使用断言验证器来验证它。

假如我们有如下的类

public class Person 
{
    public IList<Pet> Pets {get;set;} = new List<Pet>();
}

为了确保我们的list属性包含少于10个pet,我们可以这样做:

public class PersonValidator : AbstractValidator<Person>
{
    public PersonValidator() 
    {
        RuleFor(x => x.Pets).Must(list => list.Count < 10)
            .WithMessage("The list must contain fewer than 10 items");
    }
}
// 有时候我们可能还要依赖于其它的属性来做验证,Must((context,list) => list.Count < 10) context 是我们的 person对象

为了其它地方也可重复使类似的验证逻辑我们可以把它封装成一个扩展方法

public static class MyCustomValidators 
{
    public static IRuleBuilderOptions<T, IList<TElement>> ListMustContainFewerThan<T, TElement>(this IRuleBuilder<T, IList<TElement>> ruleBuilder, int num)
    {
        return ruleBuilder.Must(list => list.Count < num).WithMessage("The list contains too many items");
    }
}

然后呢我们就可以这样用它了

RuleFor(x => x.Pets).ListMustContainFewerThan(10);

自定义一个消息占位符 Custom message placeholders

public static IRuleBuilderOptions<T, IList<TElement>> ListMustContainFewerThan<T, TElement>(this IRuleBuilder<T, IList<TElement>> ruleBuilder, int num) 
{

    return ruleBuilder.Must((rootObject, list, context) => 
    {
        context.MessageFormatter
            .AppendArgument("MaxElements", num)
            .AppendArgument("TotalElements", list.Count);

        return list.Count < num;
    })
    .WithMessage("{PropertyName} must contain fewer than {MaxElements} items. The list contains {TotalElements} element");
}

可重用的属性验证器 Reusable Property Validators

有时候我们类可能会比较复杂。 我们可以对哪个类单独写一个验证器 复杂属性验证器 但是这个是对特定的某个类的。

我们还有可以使用 PropertyValidator<T, IList> 来做泛型的验让器 这是一种不太常用的方式。通常我们用前面的方式就可以满足我们的需要了。

using System.Collections.Generic;
using FluentValidation.Validators;

public class ListCountValidator<T, TCollectionElement> : PropertyValidator<T, IList<TCollectionElement>> 
{
	private int _max;

	public ListCountValidator(int max) 
    {
		_max = max;
	}

	public override bool IsValid(ValidationContext<T> context, IList<TCollectionElement> list) 
    {
		if(list != null && list.Count >= _max) 
        {
			context.MessageFormatter.AppendArgument("MaxElements", _max);
			return false;
		}

		return true;
	}

    public override string Name => "ListCountValidator";

	protected override string GetDefaultMessageTemplate(string errorCode) => "{PropertyName} must contain fewer than {MaxElements} items.";
}

为它创建一个验证器

public class PersonValidator : AbstractValidator<Person> 
{
    public PersonValidator() 
    {
        RuleFor(person => person.Pets).SetValidator(new ListCountValidator<Person, Pet>(10));
    }
}

同样可以封装到扩展方法里面

public static class MyValidatorExtensions 
{
    public static IRuleBuilderOptions<T, IList<TElement>> ListMustContainFewerThan<T, TElement>(this IRuleBuilder<T, IList<TElement>> ruleBuilder, int num) 
    {
        return ruleBuilder.SetValidator(new ListCountValidator<T, TElement>(num));
    }
}

然后我们可以这样调用它

public class PersonValidator : AbstractValidator<Person> 
{
    public PersonValidator() 
    {
        RuleFor(person => person.Pets).ListMustContainFewerThan(10);
    }
}
最近更新的
...