J'ai ce modèle
public class Person
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
Je souhaite créer une validation dans laquelle FirstName ou LastName doivent être renseignés par l'utilisateur . J'ai installé FluentValidation
et créé une classe customvalidator
public class PersonValidator:AbstractValidator<Person>
{
public PersonValidator()
{
RuleFor((person=>person.FirstName)//don't know how to check if one is empty
}
}
Pour cocher un seul champ, je pourrais simplement faire RuleFor(person => person.FirstName).NotNull();
Mais comment vérifier si l’un d’eux est nul?.
De plus, est-il possible qu'une fois la validation créée avec fluentValidation
, utilisez-la côté client pour afficher une erreur?
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>
}
Vous pouvez utiliser When/Sauf si condition:
RuleFor(m => m.FirstName).NotEmpty().When(m => string.IsNullOrEmpty(m.LastName));
RuleFor(m => m.LastName).NotEmpty().When(m => string.IsNullOrEmpty(m.FirstName));
ou
RuleFor(m => m.FirstName).NotEmpty().Unless(m => !string.IsNullOrEmpty(m.LastName));
RuleFor(m => m.LastName).NotEmpty().Unless(m => !string.IsNullOrEmpty(m.FirstName));
En ce qui concerne votre deuxième question, FluentValidation
fonctionne avec une validation côté client, mais toutes les règles ne sont pas prises en charge. Ici vous pouvez trouver des validateurs, qui sont supportés du côté client:
Pour les règles qui ne figurent pas dans la liste, vous devez écrire votre propre FluentValidationPropertyValidator
et implémenter GetClientValidationRules
. Vous pouvez trouver quelques exemples de ceci sur le StackOverflow en effectuant une recherche simple.
Essaye ça
RuleFor(person => person).Must(person => !string.IsNullOrEmpty(person.FirstName) || !string.IsNullOrEmpty(person.LastName))
Je l’ai fait pour vérifier si les frais entrés étaient identiques au précédent ou non .. Si les frais étaient identiques au précédent, il y aurait erreur. Cela a fonctionné pour moi.
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");
}
}
Voici un ensemble de règles de Nice permettant de vérifier si l'un des deux champs est vide, ainsi que d'indiquer des codes d'erreur significatifs:
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);
}
Enfin, cela a fonctionné pour moi. Je voulais valider trois propriétés où au moins une est requise. Il renvoie un message d'erreur une seule fois.
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).");