web-dev-qa-db-ja.com

FluentValidation for when&must?

ドロップダウンリストの値がyesで、フィールドが日付である必要がある場合、FluentValidation検証を使用しようとしています。ドロップダウンリストがyesの場合に機能し、dateをチェックします。しかし、Noを選択したときに検証も表示され、Must be date

ドロップダウンリストの値がyes以外の場合は、もう検証されません。どうすればそれができますか?

 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");
}
13
James123

発生している問題は、When述語が1つのルールにのみ適用されることです。 NotEmptyMustの両方で条件付き検証を行う必要があります。

これを実現するには2つの方法があります。条件付きルールが2つしかない場合は、オプション1の方が整然としています。それ以外の場合は、オプション2を使用します。

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

または

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

注:HasMaterialPublishedElseWhereTextが何であるか、またはどのように見えるかはわかりません。述語として使えると思います


編集:

HasMaterialPublishedElseWhereTextメソッドのリファクタリングも検討します。以下はエラーが発生しにくい方法です。

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

呼び出しの順序を変更するだけです。これを試して:

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

Whenは、以前のすべてのルールに適用されます。したがって、コードでNotEmptyの直後に適用した場合、NotEmptyルールにのみ適用され、Mustルールには適用されませんでした。

DotNetFiddle の完全なデモ。

9
Dinesh Gurram

VERSIONでテスト済み> = 8.4.When拡張メソッドに新しい列挙型パラメーターが追加されました

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
}

デフォルトでは(AllValidators):Whenはルールチェーンの終了で終了します

(CurrentValidator):Whenは最初の以前のルールに制限されます

0
AbuDawood