Pergunta

Usando o Nhibernate Avaliador (com S#harpa Arquitetura / MVC3), como é possível escrever um atributo personalizado, de preferência, não específicas do objeto (uma vez que esta é uma forma bastante comum de exigência) que impõe que PropertyA >= PropertyB (ou no caso mais geral, tanto pode ser nulo).

Algo como

public DateTime? StartDate { get; set; }

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

Eu vejo que eu posso substituir IsValid no particular Entity classe, mas eu não tinha certeza se aquela era a melhor abordagem, e eu não vejo como para fornecer uma mensagem nesse caso.

Foi útil?

Solução

Quando você precisa comparar as várias propriedades de um objeto, como parte da validação, você precisa de um claass avaliador.O atributo é, então, aplicado à classe e não a propriedade.

Eu não acho que há um já existente para fazer o que quiser, mas é fácil o suficiente para escrever o seu próprio.

Aqui está um código de estrutura de tópicos para mostrar que cerca o avaliador poderia olhar

[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

}

}

Outras dicas

Atualmente, se eu preciso fazer isso em um modelo, eu tenho o modelo implementar 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;
    }

Este parece proporcionar uma boa integração com o sistema existente.A desvantagem é que uma vez que esta não é aplicado no objeto de domínio, você precisa de outra lógica (ou em uma camada de serviços que cria os objetos de domínio, etc.) para impor-lo de que o fim também, no caso de um modelo diferente, que é usada em outros lugares para criar ou atualizar os objetos de domínio.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top