Я действительно периодически видел эту проблему в своем веб-приложении - в 99% случаев она работала бы нормально, но время от времени я получал эту проблему.Я обратился к Джереми Скиннеру, автору или FluentValidation, и он объяснил, что происходит:
Правила неразрывно связаны с валидаторами, которые их определяют.Они не предназначены для копирования из одного валидатора в другой.Они по своей сути связаны с валидатором, который их определил, и типом, с которым они были определены.
Каждый блок условий имеет уникальный идентификатор, связанный с ним (что позволяет кэшировать результат условия, поэтому он выполняется только один, а не для каждого правила внутри него).Когда вы копируете правила из одного валидатора в другой, условие также переносится.
Короче говоря: вы не можете разделить один объект правила между валидаторами.
Обидчикфрагмент кода: этот блок из DerivedModelValidator
:
foreach (var rule in baseValidator)
{
AddRule(rule);
}
Джереми предложил два разных решения этой проблемы:
1.Выведите оба класса валидаторов из общего базового класса валидатора, который содержит общие правила:
public abstract class CommonModelValidator<T> : AbstractValidator<T> where T : BaseModel
{
protected CommonModelValidator()
{
RuleFor(o => o.Name).Length(1, 20);
}
}
public class BaseModelValidator : CommonModelValidator<BaseModel>
{
}
public class DerivedModelValidator : CommonModelValidator<DerivedModel>
{
public DerivedModelValidator(BaseModelValidator baseValidator)
: base()
{
RuleFor(o => o.Age).GreaterThanOrEqualTo(0);
}
}
2.Составьте DerivedModelValidator
из BaseModelValidator
, используя SetValidator
:
public class BaseModelValidator : AbstractValidator<BaseModel>
{
public BaseModelValidator()
{
RuleFor(o => o.Name).Length(1, 20);
}
}
public class DerivedModelValidator : AbstractValidator<DerivedModel>
{
public DerivedModelValidator(BaseModelValidator baseValidator)
{
RuleFor(o => o).SetValidator(baseValidator);
RuleFor(o => o.Age).GreaterThanOrEqualTo(0);
}
}