FluentValidation for When & must?

≡放荡痞女 提交于 2019-12-06 19:25:29

问题


I am trying use FluentValidation validaton when dropdownlist value is yes and the field must be date. it is working when dropdownlist is yes checking for date. But also showing validation when I select No still it says Must be date.

It should not validate anymore if dropdownlist value otherthan the yes. How can we do that?

 RuleFor(x => x.DtPublishedTimeText)
            .NotEmpty()
            .When(HasMaterialPublishedElseWhereText)
            .WithMessage("Required Field")
            .Must(BeAValidDate)
            .WithMessage("Must be date");

private bool BeAValidDate(string val)
{
    DateTime date;
    return  DateTime.TryParse(val, out date);
}

private bool HasMaterialPublishedElseWhereText(MeetingAbstract model)
{
    return model.HasMaterialPublishedElseWhereText != null && 
             model.HasMaterialPublishedElseWhereText.Equals("yes");
}

回答1:


The issue you are having is the When predicate only applies to one rule. You need to have conditional validation on both the NotEmpty AND the Must.

There two ways to achieve this. Option 1 is tidier when there are only a couple of conditional rules, otherwise I'd use option 2.

RuleFor(x => x.DtPublishedTimeText)
    .NotEmpty()
        .When(HasMaterialPublishedElseWhereText)
        .WithMessage("Required Field")
    .Must(BeAValidDate)
        .When(HasMaterialPublishedElseWhereText)
        .WithMessage("Must be date");

Or

When(HasMaterialPublishedElseWhereText, () => {
    RuleFor(x => x.DtPublishedTimeText)
        .NotEmpty()
            .WithMessage("Required Field");
    RuleFor(x => x.DtPublishedTimeText)
        .Must(BeAValidDate)
            .WithMessage("Must be date");
});

Do note: I have no idea what HasMaterialPublishedElseWhereText is or what it looks like. I am assuming you can use it as a predicate


EDIT:

I'd also look at refactoring the HasMaterialPublishedElseWhereText method, the following is less error prone.

private bool HasMaterialPublishedElseWhereText(MeetingAbstract model)
{
    return String.Equals(model.HasMaterialPublishedElseWhereText, "yes", StringComparison.InvariantCultureIgnoreCase);
}



回答2:


You just need to change the order of your calls. Try this:

RuleFor(x => x.DtPublishedTimeText)
    .NotEmpty()
        .WithMessage("Required Field")
    .Must(BeAValidDate)
        .WithMessage("Must be date")
    .When(HasMaterialPublishedElseWhereText);

The When applies to all previous rules. So in your code when you applied it straight after the NotEmpty, it applied only to the NotEmpty rule and not to the Must rule.

Full demo on DotNetFiddle.




回答3:


Tested in VERSION >= 8.4.0 a new enum parameter is added to When extension method

public enum ApplyConditionTo
{
    //
    // Summary: (default)
    //     Applies the condition to all validators declared so far in the chain.
    AllValidators = 0,
    //
    // Summary:
    //     Applies the condition to the current validator only.
    CurrentValidator = 1
}

by default (AllValidators): When will ending by rules chain ends

(CurrentValidator): When will be restricted to the first previous rule



来源:https://stackoverflow.com/questions/24024896/fluentvalidation-for-when-must

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!