FluentValidation:检查两个字段中的一个是否为空

我有这个模型

public class Person { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } } 

我想创建一个validation,其中FirstName或LastName必须由用户填写。 我安装了FluentValidation并创建了一个customvalidator类

 public class PersonValidator:AbstractValidator { public PersonValidator() { RuleFor((person=>person.FirstName)//don't know how to check if one is empty } } 

要检查一个字段我可以做RuleFor(person => person.FirstName).NotNull();

但是我如何检查其中一个是否为空。

此外,一旦通过fluentValidation创建validation,是否有可能在客户端使用它来显示错误?

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 { 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(); } 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 InterestList { get; set; } } //view @model WebApplication1.Models.Person     @Html.ValidationSummary(true) @using(Html.BeginForm("AddPerson","Person",FormMethod.Post)) { 
First Name
@Html.TextBoxFor(m=>m.FirstName)@Html.ValidationMessageFor(m=>m.FirstName)

Last Name
@Html.TextBoxFor(m=>m.LastName)@Html.ValidationMessageFor(m=>m.LastName)
}

您可以使用When / unless条件:

 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适用于客户端validation,但并非所有规则都受支持。 在这里,您可以找到客户端支持的validation器:

  1. NOTNULL / NotEmpty
  2. 比赛(正则表达式)
  3. InclusiveBetween(范围)
  4. 信用卡
  5. 电子邮件
  6. EqualTo(跨财产平等比较)
  7. 长度

对于不在列表中的规则,您必须编写自己的FluentValidationPropertyValidator并实现GetClientValidationRules 。 您可以通过简单搜索在StackOverflow上找到一些这样的示例。

试试这个

 RuleFor(person => person).Must(person => !string.IsNullOrEmpty(person.FirstName) || !string.IsNullOrEmpty(person.LastName)) 

我这样做是为了检查输入的费用是否与之前相同。 如果费用与之前的费用相同,则会产生错误。 这对我有用。

 public class CasualMealChargeValidator : AbstractValidator { 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"); } } 

我不知道那个库,但是如果你只想检查这两个属性为null,那么你可以使用这个:

  RuleFor(person => person.FirstName ?? person.LastName).NotNull(); 

编辑这不起作用,因为它抛出InvalidOperationException 。 请改用Zabavsky的解决方案。

一个很好的规则集来检查两个字段中的一个是否为空,以及提出有意义的错误代码如下:

 public CustomerSourceValidator() { CascadeMode = CascadeMode.StopOnFirstFailure; RuleFor(x => x) .Null().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); } 

RuleFor(person => person).Must(person =>!string.IsNullOrEmpty(person.FirstName)||!string.IsNullOrEmpty(person.LastName))。WithName(“Name”)

最后,这对我有用。 我想validation三个属性,其中至少需要一个属性。 它只返回一次错误消息。

 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).");