在验证器类中,我有一些规则。
我需要将一些验证错误登录到数据库。
这是我的验证器:
RuleFor(u => u.LastName)
.Cascade(CascadeMode.StopOnFirstFailure)
.NotEmpty().WithMessage("Last name is required")
.Length(3, 20).WithMessage("Must have between 3 and 20 letters");
RuleFor(u => u.BirthDate)
.Cascade(CascadeMode.StopOnFirstFailure)
.NotNull().WithMessage("Birth date is required")
.Must(c => c > new DateTime(1920, 01, 01)).WithMessage("Too old");
RuleFor(u => u.Age)
.Cascade(CascadeMode.StopOnFirstFailure)
.NotNull().WithMessage("This is required")
.GreaterThan(18).WithMessage("Must be at least 18")
.Must((model, age, context) =>
{
DateTime today = DateTime.Today;
int ageToCompare = today.Year - model.BirthDate.Year;
return ageToCompare == age;
}).WithMessage("Invalid age");
对于上述规则,我只想记录特定的错误消息。
我知道我可以这样使用OnAnyFailure:
RuleFor(u => u.Age)
.Cascade(CascadeMode.StopOnFirstFailure)
.NotNull().WithMessage("This is required")
.GreaterThan(18).WithMessage("Must be at least 18").OnAnyFailure(LogOnFailure)
.Must((model, age, context) =>
{
DateTime today = DateTime.Today;
int ageToCompare = today.Year - model.BirthDate.Year;
return ageToCompare == age;
}).WithMessage("Invalid age").OnAnyFailure(LogOnFailure)
private void LogOnFailure(CreateAccountBindingModel obj))
{
Debug.WriteLine(obj);
}
但是这样一来,我将无法记录任何有用的信息,因为
OnAnyFailure
将BindingModel作为参数,因此,我只会获得用户输入的值,而不会出现错误消息。我试图创建可以用作
OnAnyFailure
的扩展方法,但是由于我是FluentValidation的新手,所以我什至无法编译我的代码。下面是我的代码:
public static class IRuleBuilderOptionsExtensions
{
public static IRuleBuilderOptions<T, TProperty> OnAnyFailure<T, TProperty>(this IRuleBuilderOptions<T, TProperty> rule, Action<T, PropertyValidatorContext> onFailure)
{
return rule;
//return rule.Configure(config => {
// config.OnFailure = onFailure.CoerceToNonGeneric();
//});
}
}
这样我可以打电话给:
private void LogOnFailure(CreateAccountBindingModel obj), PropertyValidatorContext context)
{
//log logic
}
基本上,我需要为
LogOnFailure
创建重写,使其能够访问PropertyValidatorContext。 最佳答案
您可以第二次验证模型以显示它:
public class MyValidator
{
public MyValidator()
{
// default behavior
Validate();
// works only when RuleSet specified explicitly as "Debug"
RuleSet("Debug", ()=> {
Validate();
FailAndLogErrors();
})
private void Validate()
{
RuleFor(u => u.Age)
//... set cascade mode, define rules with error messages
RuleFor(u => u.LastName)
//... set cascade mode, define rules with error messages
RuleFor(u => u.BirthDate)
//... set cascade mode, define rules with error messages
}
// force failing
private void FailAndLogErrors()
{
RuleFor(m => m)
.Must(m => false)
.WithName("_fakeProperty_")
.OnAnyFailure(m => LogIfFailed(this, m))
}
private void LogIfFailed(MyValidator validator, CreateAccountBindingModel obj))
{
var errors = validator.Validate(obj, "Debug").Errors;
if (errors.Count > 1) // prevent displaying valid model
{
var fakeError = errors.First(e => e.PropertyName == "_fakeProperty_");
errors.Remove(fakeError);
WriteErrors(errors);
}
}
private void WriteErrors(IList<ValidationFailure> errors)
{
foreach(var e in errors)
{
Debug.WriteLine(e);
}
Debug.WriteLine("");
}
}
}
关于c# - FluentValidation LogOnFailure覆盖,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38436630/