8

tengo, digamos, esta clase simple:validación utilizando atributos

public class User 
{ 
    [Required(AllowEmptyStrings = false, ErrorMessage="EmailIsRequired"] 
    public string EmailAddress { get; set; } 
} 

que saben cómo utilizar Validator.TryValidateProperty y Validator.TryValidateObject en el espacio de nombres System.ComponentModel.DataAnnotations. Para que esto funcione, necesita una instancia real del objeto que desea validar.

Pero ahora, quiero validar un cierto valor sin una instancia de la clase de usuario, como:

TryValidateValue(typeof(User), "EmailAddress", "[email protected]"); 

El objetivo es que quiero poner a prueba un valor antes de tener que crear una instancia del objeto en sí mismo (la razón es que solo permito crear entidades de dominio válidas). De hecho, quiero usar atributos de validación en clases en lugar de instancias.

Alguna idea de cómo eso podría hacerse?

Gracias!

EDITAR: mientras tanto, decidí no utilizar las anotaciones de datos, sino que usé http://fluentvalidation.codeplex.com para que la validación se moviera fuera de las entidades. De esta forma, la validación se puede activar desde dentro de las entidades y también desde mis controladores de comando. La validación en sí misma parece más legible, gracias a la notación fluida.

+0

Usted ha dicho que está tratando de evitar crear instancias de objetos de dominio si no son válidos, pero ¿cuál es el impacto de instanciándola? Es posible que su objeto esté haciendo demasiadas cosas, y debería dividir sus responsabilidades si simplemente llamar al constructor va a estropear cualquier cosa. –

+0

La entidad de dominio está comprobando todos los campos en su constructor, si alguno de ellos no valida, se lanza una excepción, por lo que no se puede crear el objeto. Pero ahora, en mi controlador de comandos, para la validación contextual necesito validar una dirección de correo electrónico, pero no necesito el objeto en sí. Entonces me preguntaba: ¿por qué no puedo reutilizar esta validación de correo electrónico sin necesidad de una instancia de este objeto? También podría eliminar la validación completamente fuera de la entidad, pero entonces no puedo usar anotaciones de datos, supongo ... –

+0

¿Hay alguna forma de crear anotaciones derivadas personalizadas? Luego puede compartir la implementación de la validación entre la anotación y para este controlador de comando. Eso sería una especie de truco, pero personalmente creo que las anotaciones no son una solución arquitectónica completa o perfectamente factorizada para la validación de restricciones de dominio (no pueden manejar restricciones de propiedad cruzada, y si se aplican a una clase, no admiten a los ricos lógica), por lo que solo harías lo mejor con lo que tienes. –

Respuesta

16

Aquí hay un ejemplo de cómo se puede utilizar el método de TryValidateValue:

public class User 
{ 
    [Required(AllowEmptyStrings = false, ErrorMessage = "EmailIsRequired")] 
    public string EmailAddress { get; set; } 
} 

class Program 
{ 
    static void Main() 
    { 
     var value = "[email protected]"; 

     var context = new ValidationContext(value, null, null);   
     var results = new List<ValidationResult>(); 
     var attributes = typeof(User) 
      .GetProperty("EmailAddress") 
      .GetCustomAttributes(false) 
      .OfType<ValidationAttribute>() 
      .ToArray(); 

     if (!Validator.TryValidateValue(value, context, results, attributes)) 
     { 
      foreach (var result in results) 
      { 
       Console.WriteLine(result.ErrorMessage); 
      } 
     } 
     else 
     { 
      Console.WriteLine("{0} is valid", value); 
     } 
    } 
} 
Cuestiones relacionadas