これは私の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.netMVC検証が実行されました。
しかし、エラーメッセージをカスタマイズしたいFluentValidationを使用。
プロパティのタイプを変更したくない次のようなさまざまな理由で:
CreatePersonValidator.cs
クラス、検証は、日付が過去であるかどうかを確認することです。
.LessThan (p => DateTime.Now)
エラーメッセージをカスタマイズする方法DataAnnotationsを使用せずに(FluentValidatorを使用して)。
public CreatePersonValidator()
{
RuleFor(courseOffering => courseOffering.StartDate)
.Must(BeAValidDate).WithMessage("Start date is required");
//....
}
private bool BeAValidDate(DateTime date)
{
return !date.Equals(default(DateTime));
}
GitHubのFluentValidationドキュメントをご覧ください。
https://github.com/JeremySkinner/FluentValidation/wiki
Less Than Validatorを適用する前に、RegEx Validatorを追加して、ユーザーの入力(文字列)が日付として正しく解析できることを確認してください。
編集
いくつかのテストケースを実行し、Fluent Validatorのソースコードを調べた結果、上記のアプローチは機能しないことを認めます。
取得する標準エラーは、モデルバインディングフェーズ中に追加されます。これは、流暢な検証フレームワークがモデルにアクセスしてチェックする前に発生します。
フレームワークの作成者は賢く、検証コードをモデルバインディングフェーズに挿入していると思いました。そうではないようです。
したがって、簡単な答えは、あなたがやりたいことは不可能に見えるということです。
スチュワートが述べたように、FluentValidationを単独で使用して、この方法でモデルバインディングの前に立つことはできません。しかし、私は2つのアイデア/提案を提供します:
これを試してください
RuleFor(f =>
f.StartDate).Cascade(CascadeMode.StopOnFirstFailure).NotEmpty()
.Must(date => date != default(DateTime))
.WithMessage("Start date is required");