FluentValidation 仅在值不为空时应用规则
FluentValidation apply rule only if the value is not empty
我有以下 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
字符串,则不应验证此规则。
在调用验证中class我可以这样做:
RuleFor(a => a.SomeProperty)
.MustHasLengthBetween(5, 10)
.When(x => !String.IsNullOrEmpty(x.SomeProperty))
它可以工作,但是我必须在每个调用方法上调用这个 When
。有什么方法可以将 When
调用移动到扩展方法吗?
在下方添加扩展 When
构建器可让您访问 属性 值。您也可以 re-use 这与其他验证。
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);
});
}
}
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");
}
});
}
我有以下 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
字符串,则不应验证此规则。
在调用验证中class我可以这样做:
RuleFor(a => a.SomeProperty)
.MustHasLengthBetween(5, 10)
.When(x => !String.IsNullOrEmpty(x.SomeProperty))
它可以工作,但是我必须在每个调用方法上调用这个 When
。有什么方法可以将 When
调用移动到扩展方法吗?
在下方添加扩展 When
构建器可让您访问 属性 值。您也可以 re-use 这与其他验证。
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);
});
}
}
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");
}
});
}