J'ai un FluentValidator qui a plusieurs propriétés comme Zip et comté, etc. Je veux créer une règle qui prend deux propriétés comme une construction RuleFor
public class FooArgs
{
public string Zip { get; set; }
public System.Guid CountyId { get; set; }
}
public class FooValidator : AbstractValidator<FooArgs>
{
RuleFor(m => m.CountyId).Must(ValidZipCounty).WithMessage("wrong Zip County");
}
Cela fonctionne mais je veux passer Zip et comté à la rue pour valider. Quelle est la meilleure méthode pour y parvenir?
Il existe une surcharge Must
qui vous fournit également l'objet FooArgs
documenté ici . Il vous permet de passer facilement les deux arguments dans votre méthode comme ceci:
RuleFor(m => m.CountyId).Must((fooArgs, countyId) =>
ValidZipCounty(fooArgs.Zip, countyId))
.WithMessage("wrong Zip County");
Je viens de tomber sur cette vieille question et je pense avoir une réponse plus simple. Vous pouvez facilement passer tout votre objet dans votre règle de validation personnalisée en simplifiant le paramètre à RuleFor
par exemple.
RuleFor(m => m).Must(fooArgs =>
ValidZipCounty(fooArgs.Zip, fooArgs.countyId))
.WithMessage("wrong Zip County");
Si la méthode ValidZipCountry
est locale à votre validateur et que vous pouvez modifier sa signature pour prendre un FooArgs
, le code se simplifie jusqu'à
RuleFor(m => m).Must(ValidZipCounty).WithMessage("wrong Zip County");
Le seul inconvénient est que le PropertyName
dans l'erreur de validation résultante sera une chaîne vide. Cela peut entraîner un problème pour votre code d'affichage de validation. Cependant, il n'est pas vraiment clair à quelle propriété l'erreur appartient aussi, ContryId
ou Zip
, donc cela a du sens.
Qu'en est-il de:
RuleFor(m => new {m.CountyId, m.Zip}).Must(x => ValidZipCounty(x.Zip, x.CountyId))
.WithMessage("wrong Zip County");
Dans mon cas, je devais marquer une propriété comme requis (x.RequiredProperty
dans l'exemple ci-dessous) si une autre propriété n'était pas nulle (x.ParentProperty
dans l'exemple ci-dessous). J'ai fini par utiliser la syntaxe When
:
RuleFor(x => x.RequiredProperty).NotEmpty().When(x => x.ParentProperty != null);
Ou si vous avez plus d'une règle pour une clause When commune, vous pouvez l'écrire comme suit:
When(x => x.ParentProperty != null, () =>
{
RuleFor(x => x.RequiredProperty).NotEmpty();
RuleFor(x => x.OtherRequiredProperty).NotEmpty();
});
La définition de la syntaxe When
est la suivante:
/// <summary>
/// Defines a condition that applies to several rules
/// </summary>
/// <param name="predicate">The condition that should apply to multiple rules</param>
/// <param name="action">Action that encapsulates the rules.</param>
/// <returns></returns>
public IConditionBuilder When (Func<T, bool> predicate, Action action);