FluentValidation: проверьте, пустое ли одно из двух полей
У меня есть эта модель
public class Person
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
Я хочу создать проверку, в которой должно быть заполнено имя FirstName или LastName пользователем.
Я установил FluentValidation
и создал класс customvalidator
public class PersonValidator:AbstractValidator<Person>
{
public PersonValidator()
{
RuleFor((person=>person.FirstName)//don't know how to check if one is empty
}
}
Чтобы проверить только одно поле, я мог бы просто сделать RuleFor(person => person.FirstName).NotNull();
Но как проверить, является ли одно из них нулевым.
Кроме того, возможно ли после создания подтверждения через FluentValidation
использовать его на стороне клиента, чтобы показать ошибку?
Edit1
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
FluentValidationModelValidatorProvider.Configure();
}
//creating validation
namespace WebApplication1.Models.CustomValidator
{
public class PersonValidator:AbstractValidator<Person>
{
public PersonValidator()
{
RuleFor(m => m.FirstName).NotEmpty().When(m => string.IsNullOrEmpty(m.LastName)).WithMessage("*Either First Name or Last Name is required");
RuleFor(m => m.LastName).NotEmpty().When(m => string.IsNullOrEmpty(m.FirstName)).WithMessage("*Either First Name or Last Name is required");
}
}
}
//model class
[Validator(typeof(PersonValidator))]
public class Person
{
public Person()
{
InterestList = new List<string>();
}
public int Id { get; set; }
public int ContactId { get; set; }
[RequiredIfEmpty("LastName")]
public string FirstName { get; set; }
[RequiredIfEmpty("FirstName")]
public string LastName { get; set; }
public string EmailAddress { get; set; }
public string Phone { get; set; }
public string Country { get; set; }
public List<string> InterestList { get; set; }
}
//view
@model WebApplication1.Models.Person
<script src="@Url.Content("~/Scripts/jquery-1.8.2.min.js")"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"></script>
<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
@Html.ValidationSummary(true)
@using(Html.BeginForm("AddPerson","Person",FormMethod.Post))
{
<div class="label">First Name</div>
<div class="input-block-level">@Html.TextBoxFor(m=>m.FirstName)@Html.ValidationMessageFor(m=>m.FirstName)</div>
<br/>
<div class="label">Last Name</div>
<div class="input-block-level">@Html.TextBoxFor(m=>m.LastName)@Html.ValidationMessageFor(m=>m.LastName)</div>
<button type="submit" class="btn-primary">Submit</button>
}
Ответы
Ответ 1
Вы можете использовать условие " Когда" или "Если":
RuleFor(m => m.FirstName).NotEmpty().When(m => string.IsNullOrEmpty(m.LastName));
RuleFor(m => m.LastName).NotEmpty().When(m => string.IsNullOrEmpty(m.FirstName));
или же
RuleFor(m => m.FirstName).NotEmpty().Unless(m => !string.IsNullOrEmpty(m.LastName));
RuleFor(m => m.LastName).NotEmpty().Unless(m => !string.IsNullOrEmpty(m.FirstName));
Что касается вашего второго вопроса, FluentValidation
работает с проверкой на стороне клиента, но не все правила поддерживаются. Здесь вы можете найти валидаторы, которые поддерживаются на стороне клиента:
- NotNull/NotEmpty
- Матчи (регулярные выражения)
- InclusiveBetween (диапазон)
- Кредитная карта
- Эл. адрес
- EqualTo (сравнение равенства свойств)
- длина
Для правил, которых нет в списке, вы должны написать свой собственный FluentValidationPropertyValidator
и реализовать GetClientValidationRules
. Вы можете найти несколько примеров этого в StackOverflow, выполнив простой поиск.
Ответ 2
Попробуйте это
RuleFor(person => person).Must(person => !string.IsNullOrEmpty(person.FirstName) || !string.IsNullOrEmpty(person.LastName))
Ответ 3
Мне понравилось это, чтобы проверить, что введенные платежи совпадают с предыдущим, или нет.
Если сборы аналогичны предыдущим, это приведет к ошибке. Это сработало для меня.
public class CasualMealChargeValidator : AbstractValidator<CasualMealCharge>
{
public CasualMealChargeValidator(CasualMealCharge CMC)
{
//RuleFor(x => x.BankName).NotEmpty().When(pm => pm.PaymentMode == "Cheque").WithMessage("Enter Bank.");
RuleFor(x => x).Must(x => x.DN != CMC.DN || x.BF != CMC.BF || x.LN != CMC.LN).WithMessage("Not Saved - Meal charges are same as current charges.").WithName("CMFor");
}
}
Ответ 4
Я не знаю эту библиотеку, но если вы просто хотите проверить эти два свойства на null, вы можете использовать это:
RuleFor(person => person.FirstName ?? person.LastName).NotNull();
РЕДАКТИРОВАТЬ Это не работает, потому что он выдает InvalidOperationException
. Вместо этого используйте решение Забавского.
Ответ 5
Хороший набор правил для проверки того, пусто ли одно из двух полей, а также для определения значимых кодов ошибок:
public CustomerSourceValidator()
{
CascadeMode = CascadeMode.StopOnFirstFailure;
RuleFor(x => x)
.NotNull().WithErrorCode("source_id_or_email_required")
.When(source => source.Email == null && source.Id == null);
RuleFor(x => x.Id)
.NotNull().WithErrorCode("source_id_required")
.Matches(CommonValidationRegex.CustomerIdRegexString).WithErrorCode("source_id_invalid")
.When(source => source.Id != null);
RuleFor(x => x.Email)
.NotNull().WithErrorCode("source_email_required")
.Matches(CommonValidationRegex.EmailRegexString).WithErrorCode("source_email_invalid")
.When(source => source.Email != null);
}
Ответ 6
RuleFor(person => person).Must(person => !string.IsNullOrEmpty(person.FirstName) || !string.IsNullOrEmpty(person.LastName)).WithName("Name")
Ответ 7
Наконец, это сработало для меня. Я хотел проверить три свойства, где требуется хотя бы одно. Он возвращает сообщение об ошибке только один раз.
RuleFor(p => p).Cascade(CascadeMode.StopOnFirstFailure)
.Must(p => !string.IsNullOrWhiteSpace(p.FirstName))
.When(p => p.Id == 0 && string.IsNullOrWhiteSpace(p.LastName)).WithMessage("At least one is required (Id, FirstName, LastName).")
.Must(p => !string.IsNullOrWhiteSpace(p.LastName))
.When(p => p.Id == 0 && string.IsNullOrWhiteSpace(p.FirstName)).WithMessage("At least one is required (Id, FirstName, LastName).")
.Must(p => p.Id != 0)
.When(p => string.IsNullOrWhiteSpace(p.FirstName) && string.IsNullOrWhiteSpace(p.LastName)).WithMessage("At least one is required (Id, FirstName, LastName).");