我此时从旧版本升级到 FluentValidation 的最新版本(11.9.0),我注意到现在我的应用程序中的错误消息包含后缀:“严重性:错误”。抛开这个想法,在我看来,当对库进行更改时,应格外小心,尽可能保持现有行为不受干扰,是否可以关闭此后缀的添加?
public ValidationException(string message, IEnumerable<ValidationFailure> errors, bool appendDefaultMessage)
: base(appendDefaultMessage ? $"{message} {BuildErrorMessage(errors)}" : message) {
Errors = errors;
}
/// <summary>
/// Creates a new ValidationException
/// </summary>
/// <param name="errors"></param>
public ValidationException(IEnumerable<ValidationFailure> errors) : base(BuildErrorMessage(errors)) {
Errors = errors;
}
private static string BuildErrorMessage(IEnumerable<ValidationFailure> errors) {
var arr = errors.Select(x => $"{Environment.NewLine} -- {x.PropertyName}: {x.ErrorMessage} Severity: {x.Severity.ToString()}");
return "Validation failed: " + string.Join(string.Empty, arr);
}
BuildErrorMessage
方法是从多个构造函数中调用的。我不知道如何才能避免它的召唤。
还有一件事。我将一些自定义验证方法附加到已验证的对象本身。默认消息显示 PropertyName,后跟冒号。如果 x.PropertyName 为 null,则消息将包含:
-- :
,这看起来很奇怪。最重要的是,有时代码中使用的名称并不反映对最终用户有意义的概念。
谢谢
更新:阅读代码后,一种方法是扩展 AbstractValidator 并重写 RaiseValidationException 以调用不装饰消息的 ValidationException 构造函数:
protected override void RaiseValidationException(ValidationContext<T> context, ValidationResult result)
=> throw new ValidationException(result.Errors, false);
不幸的是,没有带有布尔标志的构造函数,所以我也需要扩展异常。
我的解决方案是 linqpad 7 脚本,并添加了 FluentValidator 11.9.0 作为依赖项:
void Main()
{
var dto = new SomeDto();
var validator = new SomeValidator();
var result = validator.Validate(dto);
result.Dump();
}
// You can define other methods, fields, classes and namespaces here
public class ValidationExceptionEx : ValidationException
{
private static string BuildErrorMessage(IEnumerable<ValidationFailure> errors)
{
var arr = errors.Select(
x =>
{
// var propertyName = String.IsNullOrWhiteSpace(x.PropertyName) ? "" : x.PropertyName + ": ";
return $"{Environment.NewLine} -- {x.ErrorMessage}";
});
return "Validation failed: " + string.Join(string.Empty, arr);
}
public ValidationExceptionEx(List<ValidationFailure> errors) : base(BuildErrorMessage(errors), errors, false)
{
}
}
public class AbstractValidatorEx<T> : AbstractValidator<T>
{
protected override void RaiseValidationException(ValidationContext<T> context, ValidationResult result)
{
throw new ValidationExceptionEx(result.Errors);
}
}
class SomeDto { public int? SomeProperty { get; set; } }
class SomeValidator : AbstractValidatorEx<SomeDto>
{
public SomeValidator()
{
RuleFor(x => x.SomeProperty)
.NotNull()
.WithMessage(d => "Some Message");
RuleFor(x => x.SomeProperty)
.NotNull();
}
}
现在我所有的验证者都必须继承
AbstractValidatorEx
。