流畅验证 - 修剪后验证字符串

时间:2014-02-13 14:17:31

标签: fluentvalidation

我正在使用http://fluentvalidation.codeplex.com/来验证某些域模型。

我有一个典型的场景,我想验证一个字符串,例如......

RuleFor(x => x.MyString).NotNull().NotEmpty().Length(2, 20).WithMessage("Please provide a string with a minium of 2 characters.");

...在我创建一个单元测试之前,所有工作都很好用,指定MyString属性的长度必须为2-20个字符 < em>包括空格。

因此myObject.myString = "A" + new String(' ', 10);验证失败。

我可以使用.Must(IsValidString)完成所有这些操作,并将自己的所有逻辑写入...

    private bool IsValidString(string myString)
    {
       if(String.IsNullOrEmpty(myString))
           return false;

       // Then work on myString.Trim()'ed value. 
    }

...但随后我放弃了所有可爱的流利验证!!

显然我可以使用这种方法让我的单元测试通过,所有人都会在我的小世界中感到高兴,但我错过了一个技巧吗?

非常感谢。

4 个答案:

答案 0 :(得分:4)

使用http://ilspy.net/稍微查看dll FluentValidation dll,我就能获得灵感来制作以下TrimmedLengthValidator ......

public static class DefaultValidatorExtensions
    {
        public static IRuleBuilderOptions<T, string> TrimmedLength<T>(this IRuleBuilder<T, string> ruleBuilder, int min, int max)
        {
            return ruleBuilder.SetValidator(new TrimmedLengthValidator(min, max));
        }
    }

public class TrimmedLengthValidator : PropertyValidator, ILengthValidator, IPropertyValidator
    {
        public int Min { get; private set; }
        public int Max { get; private set; }

        public TrimmedLengthValidator(int min, int max)
            : this(min, max, () => Messages.length_error)
        { }

        public TrimmedLengthValidator(int min, int max, Expression<Func<string>> errorMessageResourceSelector)
            : base(errorMessageResourceSelector)
        {
            this.Max = max;
            this.Min = min;

            if (max != -1 && max < min)
                throw new ArgumentOutOfRangeException("max", "Max should be larger than min.");
        }

        protected override bool IsValid(PropertyValidatorContext context)
        {
            if (context.PropertyValue == null)
                return true;

            int length = context.PropertyValue.ToString().Trim().Length;

            if (length < this.Min || (length > this.Max && this.Max != -1))
            {
                context.MessageFormatter.AppendArgument("MinLength", this.Min).AppendArgument("MaxLength", this.Max).AppendArgument("TotalLength", length);
                return false;
            }
            return true;
        }
    }

...这意味着我可以简单地将我的验证更改为:

RuleFor(x => x.myString).NotEmpty().TrimmedLength(2, 20).WithMessage("Please provide a string with a minium of 2 characters.");

摇滚!

答案 1 :(得分:1)

我对这个框架并不熟悉,但这样的工作会不会这样? 你仍然可以保持大部分的流利程度,但检查空格需要你编写自定义验证器(这是一个很大的麻烦),或者使用Predicate验证器

RuleFor(x => x.MyString)
    .NotNull()
    .NotEmpty()
    .Length(2, 20)
        .WithMessage("Please provide a string with a minium of 2 characters.")
    .Must(myString => myString == Regex.Replace( myString, @"s", "" ))

答案 2 :(得分:0)

RuleFor(x => x.myStringBefore).Transform(c => c.Trim()).NotEmpty();

使用转换

您可以使用修剪或子字符串...(转换后)流利验证允许 将任何有效规则应用于转换后的值。

答案 3 :(得分:0)

在验证前使用 Transform 准备值:

版本:9.5+

Transform(i => i.InitialString, v => v?.Trim()).NotEmpty();

版本:9.0 - 9.4:

RuleFor(x => x.InitialString).Transform(v => v?.Trim()).NotEmpty();