对于FluentValidation
,我具有以下扩展方法:
public static IRuleBuilderOptions<T, string> MustHasLengthBetween<T>(this IRuleBuilder<T, string> rule, int min, int max)
{
return rule
.Length(min, max).WithMessage(someCustomMessage);
}
我只想在属性上有内容时才应用此规则,如果它是null
或empty
字符串,则不应验证此规则。
在调用验证类中,我可以这样:
RuleFor(a => a.SomeProperty)
.MustHasLengthBetween(5, 10)
.When(x => !String.IsNullOrEmpty(x.SomeProperty))
它可以工作,但是然后我必须将此When
调用放在每个调用方法上。有什么方法可以将When
调用移至扩展方法?
答案 0 :(得分:1)
在下面添加扩展名When
构建器可让您访问属性值。您也可以将其与其他验证一起使用。
public static IRuleBuilderOptions<T, TProperty> When<T, TProperty>(this IRuleBuilderOptions<T, TProperty> rule, Func<T, TProperty, bool> predicate, ApplyConditionTo applyConditionTo = ApplyConditionTo.AllValidators)
{
return rule.Configure(config => {
config.ApplyCondition(ctx => predicate((T)ctx.Instance, (TProperty)ctx.PropertyValue), applyConditionTo);
});
}
public class UnitTest1
{
[Fact]
public void Should_validate_length ()
{
var ok1 = new Model { MyProperty = null };
var ok2 = new Model { MyProperty = "" };
var ok3 = new Model { MyProperty = "55555" };
var fail = new Model { MyProperty = "1" };
var v = new ModelValidator ();
v.ValidateAndThrow (ok1);
v.ValidateAndThrow (ok2);
v.ValidateAndThrow (ok3);
Should.Throw<ValidationException> (() => v.ValidateAndThrow (fail));
}
public class Model
{
public string MyProperty { get; set; }
}
public class ModelValidator : AbstractValidator<Model>
{
public ModelValidator ()
{
RuleFor (x => x.MyProperty)
.MustHaveLengthBetween (5, 10);
}
}
}
public static class Extensions
{
public static IRuleBuilderOptions<T, string> MustHaveLengthBetween<T> (this IRuleBuilder<T, string> rule, int min, int max)
{
return rule
.Length (min, max).WithMessage ("AGAGA")
.When ((model, prop) => !string.IsNullOrEmpty (prop));
}
/// <summary>
/// Predicate builder which makes the validated property available
/// </summary>
/// <param name="IRuleBuilderOptions<T"></param>
/// <param name="rule"></param>
/// <param name="predicate"></param>
/// <param name="applyConditionTo"></param>
/// <typeparam name="T"></typeparam>
/// <typeparam name="TProperty"></typeparam>
/// <returns></returns>
public static IRuleBuilderOptions<T, TProperty> When<T, TProperty> (this IRuleBuilderOptions<T, TProperty> rule, Func<T, TProperty, bool> predicate, ApplyConditionTo applyConditionTo = ApplyConditionTo.AllValidators)
{
return rule.Configure (config =>
{
config.ApplyCondition (ctx => predicate ((T) ctx.Instance, (TProperty) ctx.PropertyValue), applyConditionTo);
});
}
}
答案 1 :(得分:1)
public static IRuleBuilderInitial<T, string> MustHasLengthBetween<T>(this IRuleBuilder<T, string> rule, int min, int max)
{
return rule.Custom((obj, context) =>
{
if (!String.IsNullOrEmpty(obj) && (obj.Length < min || obj.Length > max))
{
context.AddFailure("custom message");
}
});
}