Подтвердить дату с помощью FluentValidator
Это мой класс 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 = "");
}
}
При попытке создать человека с недопустимым форматом даты:
![Error trying to save the person]()
Наблюдения
Как и в моем классе CreatePersonModel, свойство DateBirth
является типом DateTime
, для меня выполнена проверка asp.net MVC.
Но я хочу настроить сообщение об ошибке с помощью FluentValidation.
Я не хочу изменять тип свойства по различным причинам, например:
В классе CreatePersonValidator.cs
проверка должна проверить, была ли дата в прошлом:
.LessThan (p => DateTime.Now)
Вопрос
Как настроить сообщение об ошибке без использования DataAnnotations (используя FluentValidator).
Ответы
Ответ 1
public CreatePersonValidator()
{
RuleFor(courseOffering => courseOffering.StartDate)
.Must(BeAValidDate).WithMessage("Start date is required");
//....
}
private bool BeAValidDate(DateTime date)
{
return !date.Equals(default(DateTime));
}
Ответ 2
Посмотрите документацию Fluent Validation на GitHub:
https://github.com/JeremySkinner/FluentValidation/wiki
Попробуйте добавить RegEx Validator, чтобы убедиться, что пользовательский ввод (строка) может быть проанализирован как дата правильно, до применения Менеджера проверки менее.
ИЗМЕНИТЬ
Запустив несколько тестовых примеров и посмотрев исходный код для Fluent Validator, я признаю, что вышеупомянутый подход не будет работать.
Стандартная ошибка, которую вы получаете, добавляется во время фазы привязки модели, которая происходит до того, как свободная структура проверки может получить доступ и проверить модель.
Я предположил, что авторы фреймворков были умны и вводили свой код проверки в фазу привязки модели. Похоже, что это не так.
Итак, короткий ответ - это то, что вы хотите сделать, не представляется возможным.
Ответ 3
Как упоминал Стюарт, невозможно использовать FluentValidation в одиночку, чтобы таким образом получить привязку к модели. Я бы предложил две идеи/предложения:
- Если вы действительно не можете изменить тип ViewModel с DateTime на строку, , вы всегда можете очистить состояние модели после привязки к модели, а затем запустить проверку подлинности вручную (я предполагаю, что вы проводной FluentValidation для автоматического выполнения после привязки модели).
- В таких сценариях я бы изменил свойство на строку, но затем используйте AutoMapper, чтобы сопоставить это в DateTime для чего-либо бизнес-объект/модель домена/запрос на обслуживание службы. Мне это нужно в конечном итоге. Таким образом, вы получаете максимальную гибкость при анализе и преобразовании с обеих сторон привязки модели.
Ответ 4
Попробуйте этот
RuleFor(f =>
f.StartDate).Cascade(CascadeMode.StopOnFirstFailure).NotEmpty()
.Must(date => date != default(DateTime))
.WithMessage("Start date is required");