Pregunta

Usando Nhibernate Validator (con S#harp Architecture/MVC3), ¿cómo puedo escribir un atributo personalizado, preferiblemente no específico de objeto (ya que este es un requisito bastante común) que impone que PropiedadA >= PropiedadB (o en el caso más general, ambos pueden ser nulos).

Algo como

public DateTime? StartDate { get; set; }

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

Veo que puedo anular IsValid en particular Entity class pero no estaba seguro de si ese era el mejor enfoque y no veía cómo proporcionar un mensaje en ese caso.

¿Fue útil?

Solución

Cuando necesita comparar varias propiedades de un objeto como parte de la validación, necesita un validador de clauss.El atributo se aplica luego a la clase, no a la propiedad.

No creo que haya uno existente para hacer lo que quiera, pero es lo suficientemente fácil de escribir el suyo.

Aquí hay un contorno de código para mostrarle aproximadamente cómo podría parecer su validador

[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

}

}

Otros consejos

Actualmente, si necesito hacer esto en un modelo, tengo el modelo implementado 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;
    }

Esto parece proporcionar una buena integración con el sistema existente.El inconveniente es que, dado que esto no se aplica al objeto de dominio, necesita lógica adicional allí (o en una capa de servicios que crea los objetos de dominio, etc.) para aplicarlo también desde ese extremo, en caso de que se use un modelo diferente en otro lugar. para crear o actualizar los objetos del dominio.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top