如何在fluent验证中使用扩展方法生成自定义错误消息


public class Validator : AbstractValidator<Command>
{
public Validator(ICheckExists<ICheckEntityExists> checkEntityExists)
{
RuleFor(x => x)
.EntityDoesNotExist(checkEntityExists, c => new CheckEntityExists()
{
TypeId = c.Id,
StatusId = c.StatusId
});
}

嗨,我有个问题。上面的代码生成"must not exist"错误消息。EntityDoesNotExist是一个我无法更改的扩展方法。由于这是一种扩展方法,我不能使用任何OverridePropertyNameWithNameWithMessage
问题是如何将错误消息更改为自定义消息。我已经写了这个代码,它做

ValidatorOptions.Global.DisplayNameResolver = (type, member, expression) =>
{
if (member == null)
{
return "Hello world";
}
return member.Name;
};

但只有当我有一条规则没有名字,而且看起来不漂亮时,它才有效。也许还有另一种方法可以达到同样的结果?

问题是您使用的扩展方法返回了一个IRuleBuilder<T, out TProperty>接口的实例,该实例不包含WithMessage等方法的定义。这个方法和您提到的其他方法是继承IRuleBuilder<T, out TProperty>IRuleBuilderOptions<T, TProperty>接口的扩展方法。

因此,一种可能的解决方案是将EntityDoesNotExist扩展方法封装到另一种方法中,该方法将返回的类型下变频到IRuleBuilderOptions<T, TProperty>

例如,我们有一个名为Person:的类

public class Person
{
public string Name { get; set; } = null!;
}

返回IRuleBuilder类型的Name属性的扩展方法:

public static IRuleBuilder<T, string> ValidateNameLength<T>(this IRuleBuilder<T, string> ruleBuilder)
{
return ruleBuilder.Must(name => name.Length < 5).WithMessage("Incorrect length");
}

所以我们可以把这个方法包装成这样:

public static IRuleBuilderOptions<T, string> ValidateNameLengthWrapper<T>(this IRuleBuilder<T, string> ruleBuilder)
{
return (IRuleBuilderOptions<T, string>) ruleBuilder.ValidateNameLength();
}

然后我们可以使用WithMessage方法来覆盖错误描述:

public class Validator : AbstractValidator<Person>
{
public Validator()
{
CascadeMode = CascadeMode.Continue;
RuleFor(x => x.Name!).ValidateNameLengthWrapper().WithMessage("Name must be less than 5 characters");
}
}

但是,最好编写自己的扩展方法,或者在验证上下文之外解决问题。

最新更新