Question

En utilisant le validateur nhibernate (avec S # Harp Architecture / MVC3), comment puis-je écrire un attribut personnalisé, de préférence non spécifique à un objet (car il s'agit d'une exigence assez courante) qui applique que PropertyA> = PropertyB (ou dans le cas plus général, Les deux peuvent être nuls).

Quelque chose comme

public DateTime? StartDate { get; set; }

[GreaterThanOrEqual("StartDate")]
public DateTime? EndDate { get; set; }

Je vois que je peux remplacer IsValid en particulier Entity classe mais je ne savais pas si c'était la meilleure approche, et je n'ai pas vu comment fournir un message dans ce cas.

Était-ce utile?

La solution

Lorsque vous devez comparer plusieurs propriétés d'un objet dans le cadre de la validation, vous avez besoin d'un validateur CLAASS. L'attribut est ensuite appliqué à la classe, pas à la propriété.

Je ne pense pas qu'il y ait un existant pour faire ce que vous voulez, mais il est assez facile d'écrire le vôtre.

Voici un plan de code pour vous montrer à peu près à quoi pourrait ressembler votre validateur

[AttributeUsage(AttributeTargets.Class)]
[ValidatorClass(typeof(ReferencedByValidator))]
public class GreaterThanOrEqualAttribute : EmbeddedRuleArgsAttribute, IRuleArgs
{        
    public GreaterThanOrEqualAttribute(string firstProperty, string secondProperty)
    {
        /// Set Properties etc
    }
}

public class ReferencedByValidator : IInitializableValidator<GreaterThanOrEqualAttribute>
{       
    #region IInitializableValidator<ReferencedByAttribute> Members

    public void Initialize(GreaterThanOrEqualAttribute parameters)
    {
        this.firstProperty = parameters.FirstProperty;
        this.secondProperty = parameters.SecondProperty;
    }

    #endregion

    #region IValidator Members

    public bool IsValid(object value, IConstraintValidatorContext constraintContext)
    {
       // value is the object you are trying to validate

        // some reflection code goes here to compare the two specified properties
   }
    #endregion

}

}

Autres conseils

Actuellement, si j'ai besoin de le faire sur un modèle, j'ai le modèle d'implémentation IValidatableObject

public class DateRangeModel : IValidatableObject {

   public DateTime StartDate { get; set; }
   public DateTime EndDate { get; set; }


   public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        List<ValidationResult> results = new List<ValidationResult>();
        if (StartDate > EndDate)
        {
            results.Add(new ValidationResult("The Start Date cannot be before the End Date.", "StartDate"));
        }
        return results;
    }

Cela semble fournir une bonne intégration avec le système existant. L'inconvénient est que comme cela n'est pas appliqué sur l'objet de domaine, vous avez besoin d'une logique supplémentaire (ou dans une couche de services qui crée les objets de domaine, etc.) pour l'appliquer à partir de cette fin, au cas où un modèle différent est utilisé ailleurs pour créer ou mettre à jour les objets de domaine.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top