FluentValidation中有可能为RuleSet提供特定的错误消息吗?
类似的东西:
RuleSet("LoginInformation", () =>
{
RuleFor(m => m.Email).NotEmpty().EmailAddress();
RuleFor(m => m.Password).NotEmpty();
}); // I thought I can add a WithMessage here...
如果任何规则失败,则应显示单个错误消息。
答案 0 :(得分:1)
简单解决方案
在不更改FluentValidation源的情况下,无法直接将错误消息设置为RuleSet
,但您可以在特殊列表中收集规则,并在循环中设置相同的错误消息:
RuleSet("LoginInformation", () =>
{
var loginRules = new List<IRuleBuilderOptions<CredentialsModel, object>>
{
RuleFor(m => m.Email).NotEmpty().EmailAddress(),
RuleFor(m => m.Password).NotEmpty()
};
foreach (var rule in rules)
{
// this overload chosen just to show, that all possibilities to set error message still available
rule.WithMessage("An error occured. Additional information: {0}, {1}", (model, value) => value, (model, value) => model.Email);
}
});
只有2 cascade mode options,你无法告诉验证者在第一次失败时停止所有规则,所以你只需要从验证结果中取出第一个错误并删除其他相同的错误。为此,您可以覆盖AbstractValidator
:
public class SingleErrorValidator<T> : AbstractValidator<T>
{
public override ValidationResult Validate(ValidationContext<T> context)
{
var result = base.Validate(context);
if (result.IsValid)
return result;
var singleErrorList = new List<ValidationFailure> { result.Errors.First() };
var singleErrorResult = new ValidationResult(singleErrorList);
return singleErrorResult;
}
}
高级解决方案:
如果您分叉了FluentValidation并且可以修改解决方案中的源代码,那么您可以为常见错误消息制作可重用的方法,并在RuleSet
类中添加下一个AbstractValidator
方法重载(您不能使用扩展方法或继承,因为重要字段具有私有修饰符):
public void RuleSet(string ruleSetName, Func<List<IRuleBuilderOptions<T, object>>> function, Action<IRuleBuilderOptions<T, object>> writeRuleMessage)
{
ruleSetName.Guard("A name must be specified when calling RuleSet.");
function.Guard("A ruleset definition must be specified when calling RuleSet.");
using (nestedValidators.OnItemAdded(r => r.RuleSet = ruleSetName))
{
var list = function();
foreach (var rule in list)
{
writeRuleMessage(rule);
}
}
}
然后您可以使用RuleSet
下一个方式:
RuleSet("LoginInformation", () =>
{
var rules = new List<IRuleBuilderOptions<B, object>>()
{
RuleFor(x => x.Name).NotEmpty().EmailAddress(),
RuleFor(x => x.Email).NotEmpty()
};
return rules;
}, (rule) =>
{
rule.WithMessage("An error occured");
}); // still can use another overloads, that allow access to model and validated properties
<强>结论强>
两种解决方案都能够正常工作,但由于KISS原则,我建议使用1-st。