26

これは私のViewModelクラスです:

public class CreatePersonModel
{
    public string Name { get; set; }
    public DateTime DateBirth { get; set; }
    public string Email { get; set; }
}

CreatePerson.cshtml

@model ViewModels.CreatePersonModel
@{
    ViewBag.Title = "Create Person";
}

<h2>@ViewBag.Title</h2>

@using (Html.BeginForm())
{
    <fieldset>
        <legend>RegisterModel</legend>

        @Html.EditorForModel()

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

CreatePersonValidator.cs

public class CreatePersonValidator : AbstractValidator<CreatePersonModel>
{
    public CreatePersonValidator()
    {
        RuleFor(p => p.Name)
            .NotEmpty().WithMessage("campo obrigatório")
            .Length(5, 30).WithMessage("mínimo de {0} e máximo de {1} caractéres", 5, 30)
            .Must((p, n) => n.Any(c => c == ' ')).WithMessage("deve conter nome e sobrenome");

        RuleFor(p => p.DateBirth)
            .NotEmpty().WithMessage("campo obrigatório")
            .LessThan(p => DateTime.Now).WithMessage("a data deve estar no passado");

        RuleFor(p => p.Email)
            .NotEmpty().WithMessage("campo obrigatório")
            .EmailAddress().WithMessage("email inválido")
            .OnAnyFailure(p => p.Email = "");
    }
}

無効な日付形式で個人を作成しようとすると:

ユーザーの保存中にエラーが発生しました

観察

私の CreatePersonModel クラスのように、DateBirthプロパティはDateTime型であり、asp.net MVC の検証が行われました。

しかし、 FluentValidation を使用してエラー メッセージをカスタマイズしたいと考えています。

次のようなさまざまな理由で、プロパティのタイプを変更したくありません。

クラスではCreatePersonValidator.cs 、検証とは日付が過去のものかどうかを確認することです。

.LessThan (p => DateTime.Now)

質問

DataAnnotations を使用せずに (FluentValidator を使用して)エラー メッセージをカスタマイズする方法。

4

5 に答える 5

29
public CreatePersonValidator()
{
    RuleFor(courseOffering => courseOffering.StartDate)
       .Must(BeAValidDate).WithMessage("Start date is required");

    //....
}

private bool BeAValidDate(DateTime date)
{
    return !date.Equals(default(DateTime));
}
于 2012-08-31T10:08:06.277 に答える
4

GitHub の Fluent Validation ドキュメントをご覧ください。

https://github.com/JeremySkinner/FluentValidation/wiki

Less Than Validator を適用する前に、RegEx Validator を追加して、ユーザーの入力 (文字列) が日付として正しく解析されることを確認してください。

編集

いくつかのテスト ケースを実行し、Fluent Validator のソース コードを調べた結果、上記のアプローチが機能しないことを認めます。

取得する標準エラーは、流暢な検証フレームワークがモデルにアクセスしてチェックする前に発生するモデル バインディング フェーズ中に追加されます。

フレームワークの作成者は賢く、検証コードをモデル バインディング フェーズに挿入していると思いました。そうではないようです。

したがって、簡単な答えは、あなたがやりたいことは不可能だと思われるということです。

于 2011-10-18T13:27:15.257 に答える
1

Stewart が述べたように、FluentValidation を単独で使用して、このようにモデル バインディングの前に立つことはできません。ただし、2つのアイデア/提案を提供します。

  1. ViewModel 型を DateTime から文字列に本当に変更できない場合は、モデル バインド後にモデルの状態を自分でクリアし、バリデーターを手動で実行できます (モデル バインド後に FluentValidation を自動的に実行するように配線したと仮定しています)。
  2. このようなシナリオでは、プロパティを文字列に変更しますが、AutoMapperを使用して、最終的に必要なビジネス オブジェクト / ドメイン モデル / サービス コントラクト リクエストの DateTime にマップします。 こうすることで、モデル バインディングの両側で解析と変換を最大限に柔軟に行うことができます。
于 2012-02-08T03:07:03.503 に答える
1

これを試してみてください

RuleFor(f =>
        f.StartDate).Cascade(CascadeMode.StopOnFirstFailure).NotEmpty()
                    .Must(date => date != default(DateTime))
                    .WithMessage("Start date is required");
于 2015-07-16T05:53:59.503 に答える