簡體   English   中英

僅當值不為空時,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);
    }

我只想在屬性上有內容時才應用此規則,如果它是nullempty字符串,則不應驗證此規則。

在調用驗證類中,我可以這樣:

        RuleFor(a => a.SomeProperty)
            .MustHasLengthBetween(5, 10)
            .When(x => !String.IsNullOrEmpty(x.SomeProperty))

它可以工作,但隨后我必須在每個調用方法上都放置此When調用。 有什么方法可以將When調用移至擴展方法嗎?

添加擴展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);
        });
    }
}
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");
                }
            });
        }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM