ドロップダウンリストの値が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");
}
発生している問題は、When
述語が1つのルールにのみ適用されることです。 NotEmpty
とMust
の両方で条件付き検証を行う必要があります。
これを実現するには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);
}
呼び出しの順序を変更するだけです。これを試して:
RuleFor(x => x.DtPublishedTimeText)
.NotEmpty()
.WithMessage("Required Field")
.Must(BeAValidDate)
.WithMessage("Must be date")
.When(HasMaterialPublishedElseWhereText);
When
は、以前のすべてのルールに適用されます。したがって、コードでNotEmpty
の直後に適用した場合、NotEmpty
ルールにのみ適用され、Must
ルールには適用されませんでした。
DotNetFiddle の完全なデモ。
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
は最初の以前のルールに制限されます