具有来自基本实体的参数的 FluentValidation 自定义扩展方法
FluentValidation Custom Extension Method with Parameters from Base Entity
我正在使用 FluentValidation 进行服务器验证,其中一项验证使用带有参数的自定义扩展方法。所述方法将需要来自根对象(实体)的更多参数。
目前代码是:
RuleFor(entity => entity.A).CustomExtension("test")
...
public static IRuleBuilder<T, string> CustomExtension<T>(this IRuleBuilder<T, string> builder, string someValue){
我需要更改它以便...
RuleFor(entity => entity.A).CustomExtension(entity.PropertyB) //<- basically need to pass a entity property as variable
public static IRuleBuilder<T, string> CustomExtension<T>(this IRuleBuilder<T, string> builder, string propertyA){
}
非常感谢任何帮助!
您无权访问要在验证器构造期间进行验证的实例。可能有几种方法可以做到这一点,这可能取决于您要实施的规则类型。
我想到的两种方法是利用现有的 custom validators that provide the instance to validate (directly or via context). The former gives you just that, the instance passed to the validator, the latter additionally gives you a context,您可以使用它在 运行 时向验证器提供数据。
假设您可以使用 Must 扩展来创建您的自定义验证器,这意味着我们正在研究前一种情况。必须有一些重载,其中之一提供被验证为 Func lambda 一部分的实例。以下 LINQPad 示例展示了如何利用它来创建自己的扩展:
void Main()
{
var validator = new MyValidator();
var myEntity1 = new MyEntity();
myEntity1.A = Guid.NewGuid();
myEntity1.B = myEntity1.A;
var validateResult1 = validator.Validate(myEntity1);
Console.WriteLine("Expected result: no errors");
Console.WriteLine(validateResult1.Errors.Select(x => x.ErrorMessage));
var myEntity2 = new MyEntity();
myEntity2.A = Guid.NewGuid();
myEntity2.B = Guid.NewGuid();
var validateResult2 = validator.Validate(myEntity2);
Console.WriteLine("Expected result: 3 errors");
Console.WriteLine(validateResult2.Errors.Select(x => x.ErrorMessage));
}
public class MyEntity
{
public Guid A { get; set; }
public Guid B { get; set; }
}
public class MyValidator : AbstractValidator<MyEntity>
{
public MyValidator()
{
RuleFor(x => x.A).Equal(x => x.B).WithMessage("Error via equal");
RuleFor(x => x.A).Must((myEntityInstance, valueOfA) => myEntityInstance.B.Equals(valueOfA)).WithMessage("Error via normal must");
RuleFor(x => x.A).CustomExtension(x => x.B).WithMessage("Error via custom extension");
}
}
public static class Extensions
{
public static IRuleBuilderOptions<T, TProperty> CustomExtension<T, TProperty, TCompareTo>
(this IRuleBuilder<T, TProperty> ruleBuilder, Func<T, TCompareTo> propertyToCompareTo)
{
return ruleBuilder.Must((myEntityInstance, valueOfA) => propertyToCompareTo(myEntityInstance).Equals(valueOfA));
}
}
结果:
在不知道您的自定义扩展将要做什么的情况下,这有点做作,但它确实展示了一种在您自己的扩展中获取实例以在 运行 时间进行验证的方法。
我正在使用 FluentValidation 进行服务器验证,其中一项验证使用带有参数的自定义扩展方法。所述方法将需要来自根对象(实体)的更多参数。
目前代码是:
RuleFor(entity => entity.A).CustomExtension("test")
...
public static IRuleBuilder<T, string> CustomExtension<T>(this IRuleBuilder<T, string> builder, string someValue){
我需要更改它以便...
RuleFor(entity => entity.A).CustomExtension(entity.PropertyB) //<- basically need to pass a entity property as variable
public static IRuleBuilder<T, string> CustomExtension<T>(this IRuleBuilder<T, string> builder, string propertyA){
}
非常感谢任何帮助!
您无权访问要在验证器构造期间进行验证的实例。可能有几种方法可以做到这一点,这可能取决于您要实施的规则类型。
我想到的两种方法是利用现有的 custom validators that provide the instance to validate (directly or via context). The former gives you just that, the instance passed to the validator, the latter additionally gives you a context,您可以使用它在 运行 时向验证器提供数据。
假设您可以使用 Must 扩展来创建您的自定义验证器,这意味着我们正在研究前一种情况。必须有一些重载,其中之一提供被验证为 Func lambda 一部分的实例。以下 LINQPad 示例展示了如何利用它来创建自己的扩展:
void Main()
{
var validator = new MyValidator();
var myEntity1 = new MyEntity();
myEntity1.A = Guid.NewGuid();
myEntity1.B = myEntity1.A;
var validateResult1 = validator.Validate(myEntity1);
Console.WriteLine("Expected result: no errors");
Console.WriteLine(validateResult1.Errors.Select(x => x.ErrorMessage));
var myEntity2 = new MyEntity();
myEntity2.A = Guid.NewGuid();
myEntity2.B = Guid.NewGuid();
var validateResult2 = validator.Validate(myEntity2);
Console.WriteLine("Expected result: 3 errors");
Console.WriteLine(validateResult2.Errors.Select(x => x.ErrorMessage));
}
public class MyEntity
{
public Guid A { get; set; }
public Guid B { get; set; }
}
public class MyValidator : AbstractValidator<MyEntity>
{
public MyValidator()
{
RuleFor(x => x.A).Equal(x => x.B).WithMessage("Error via equal");
RuleFor(x => x.A).Must((myEntityInstance, valueOfA) => myEntityInstance.B.Equals(valueOfA)).WithMessage("Error via normal must");
RuleFor(x => x.A).CustomExtension(x => x.B).WithMessage("Error via custom extension");
}
}
public static class Extensions
{
public static IRuleBuilderOptions<T, TProperty> CustomExtension<T, TProperty, TCompareTo>
(this IRuleBuilder<T, TProperty> ruleBuilder, Func<T, TCompareTo> propertyToCompareTo)
{
return ruleBuilder.Must((myEntityInstance, valueOfA) => propertyToCompareTo(myEntityInstance).Equals(valueOfA));
}
}
结果:
在不知道您的自定义扩展将要做什么的情况下,这有点做作,但它确实展示了一种在您自己的扩展中获取实例以在 运行 时间进行验证的方法。