Mostrando entradas con la etiqueta VAP. Mostrar todas las entradas
Mostrando entradas con la etiqueta VAP. Mostrar todas las entradas

viernes, 27 de julio de 2007

¿Cómo crear un Custom Validator para VAB de EntLib 3.1?

Introducción Ya vimos como se utiliza el VAP de EntLib 3.1, más adelante vamos a ver la integración con Winforms y ASP.NET (dos cosas muy interesantes) pero ahora es momento de aprender a crear nuestros propios validadores. Esto es muy útil para realizar validaciones que no se pueden con los elementos que trae VAP por defecto, en este caso vamos a ver un ejemplo de cómo realizar la validación de un número de CUIT/ CUIL de Argentina. Teoría Para poder crear nuestros Validators y que EntLib los acepte son necesarias dos cosas.
  • Que nuestra clase herede de Validator
  • Que nuestra clase esté adornado con el atributo CustomValidatorData
Con esto es suficiente, obviamente al heredar de Validator (que es una clase abstracta) tenemos que implementar dos métodos
  • DoValidate
  • DefaultMessageTemplate
Pero, alto, hace falta algo más que no es tan fácil de deducir, nuestra clase tiene que tener un constructor que acepte un parámetro del tipo NameValueCollection esto es para que EntLib le pase los atributos de la configuración, pero repito, no lo dice por ningún lado así que cuidado porque sino nos va a dar un error al querer realizar la validación no antes. Veamos el código.
   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Text;
   4:  using System.Configuration;
   5:  using Microsoft.Practices.EnterpriseLibrary.Validation;
   6:  using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
   7:  using System.Collections.Specialized;
   8:   
   9:  namespace Validadores
  10:  {
  11:      [ConfigurationElementType(typeof(Microsoft.Practices.EnterpriseLibrary.Validation.Configuration.CustomValidatorData))]
  12:      public class CuitValidator: Validator
  13:      {
  14:          public CuitValidator():base(null,null) { }
  15:          public CuitValidator(NameValueCollection values): base(null,null)
  16:          {
  17:          }
  18:          protected override string DefaultMessageTemplate
  19:          {
  20:              get { return "El CUIT ingresado no es válido"; }
  21:          }
  22:   
  23:          protected override void DoValidate(object objectToValidate, object currentTarget, string key, ValidationResults validationResults)
  24:          {
  25:              if (objectToValidate != null)
  26:              {
  27:                  bool valido = CUIT.Validar((string)objectToValidate);
  28:                  if(!valido)
  29:                      base.LogValidationResult(validationResults, this.DefaultMessageTemplate, currentTarget, key);
  30:              }
  31:          }
  32:      }
  33:  }
con esto es suficiente, el método DefaultMessageTemplate permite recuperar el mensaje de error por defecto, el método DoValidate realiza la validación, como se puede ver tenemos una clase CUIT con un método estático Validar que utilizamos para validar y es todo, si la validación es incorrecta llamamos a base.LogValidationResult que agrega nuestro mensaje a ValidationResults la colección que contendrá los errores en la validación, no es necesario hacer nada más que esto para poder utilizar nuestro validador configurando el application block desde el archivo de configuración, ahora, si queremos poder agregar como atributo en alguna propiedad nuestro validador hay que hacer trabajo adicional, pero no se asusten, es simple. Validar con atributos
   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Text;
   4:  using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;
   5:   
   6:  namespace Validadores
   7:  {
   8:      public class CuitValidatorAttribute: ValidatorAttribute
   9:      {
  10:          protected override Microsoft.Practices.EnterpriseLibrary.Validation.Validator DoCreateValidator(Type targetType)
  11:          {
  12:              return new CuitValidator();
  13:          }
  14:      }
  15:  }
sencillo, sólo hay que heredar la clase abstracta ValidatorAttribute que tiene un sólo método, y lo que tenemos que hacer es retornar una instacia de nuestro validador y listo. Namespace utilizados: System.Configuration; Microsoft.Practices.EnterpriseLibrary.Validation; Microsoft.Practices.EnterpriseLibrary.Common.Configuration; System.Collections.Specialized; Microsoft.Practices.EnterpriseLibrary.Validation.Validators; PD: El código para realizar la validación se los dejo de tarea :) .

viernes, 20 de julio de 2007

Validaton Application Block desde Web Config

Introducción En la entrada anterior vimos como crear validaciones agregando atributos a nuestras clases, ahora vamos a ver como podemos hacer el mismo trabajo sin tocar para nada las clases, incluso podemos aplicar reglas de validación a clases a las cuales no tenemos acceso al código, todo gracias al VAP. Comencemos Tomemos nuestra clase y quitemos todos los atributos.
1:     public class Persona
2:     {
3:         private int _edad;
4:         private string _nombre;
5:         private string _apellido;
6:         private string _email;
7:  
8:         public string Email
9:         {
10:             get { return _email; }
11:             set { _email = value; }
12:         }
13:         public string Apellido
14:         {
15:             get { return _apellido; }
16:             set { _apellido = value; }
17:         }
18:         public string Nombre
19:         {
20:             get { return _nombre; }
21:             set { _nombre = value; }
22:         }
23:         public int Edad
24:         {
25:             get { return _edad; }
26:             set { _edad = value; }
27:         }
28:     }
Ahora, agregamos un App.Config y lo abrimos con el editor de EntLib. Acto seguimos hacemos click derecho y seleccionamos Add Validation Application Block Acto seguido seleccionado Add New Rule Set y le ponemos de nombre Default Luego agregamos un nuevo tipo, con esto vamos a agregar nuestra clase Persona. Buscamos el tipo en el cuadro que aparece y luego hacemos botón derecho y selecionamos Choose Members Y seleccionamos las propiedades que queremos validar Hacemos botón derecho sobre el Apellido (por ejemplo) y seleccionado New -> Not Null Validator Presionamos F4 y modificamos sus propiedades para que nos muestre un mensaje en caso de no superar la validación desde la propiedad Message Template Y seguimos agregando los validadores, utilizamos el código de validación que vimos antes
   1:              Persona p = new Persona();
   2:   
   3:              Console.WriteLine("Ingrese nombre");
   4:              p.Nombre = Console.ReadLine();
   5:   
   6:              Console.WriteLine("Ingrese apellido");
   7:              p.Apellido = Console.ReadLine();
   8:   
   9:              Console.WriteLine("Ingrese edad");
  10:              p.Edad = Convert.ToInt32(Console.ReadLine());
  11:   
  12:              Console.WriteLine("Ingrese email");
  13:              p.Email = Console.ReadLine();
  14:   
  15:              ValidationResults results = ValidationFactory.CreateValidator("Default").Validate(p);
  16:   
  17:              if (!results.IsValid)
  18:              {
  19:   
  20:                  StringBuilder sb = new StringBuilder("Errores de validación");
  21:                  sb.AppendLine();
  22:   
  23:                  foreach (ValidationResult result in results)
  24:                  {
  25:                      sb.AppendLine(result.Message);
  26:                  }
  27:   
  28:                  Console.WriteLine(sb.ToString());
  29:              }
  30:              else
  31:              {
  32:                  Console.WriteLine("todo bien");
  33:              }

Lo corremos y eureka!! funciona, buenísimo y muy flexible. En la próxima vemos como hacer nuestros propios validadores.

jueves, 19 de julio de 2007

Introducción al Validation Application Block

Introducción Para los que no lo conocen el Validation Application Block es parte de la Enterprise Library desde hace tiempo, si bien, creo que ahora con la 3.1 con los adaptadores para winforms, asp.net y wcf se puede decir que está "completo", pero eso lo vamos a ver más adelante, comencemos por el principio. Proceso de validación Pocas cosas son más molestas que las validaciones (y trabajosas) sobre todo porque enmarañan el código y si no están correctas cambiarlas suele ser un problema. Bien el VAB (validation app block) viene en nuestra ayuda. VAP nos va a permitir escribir un pequeño código para realizar el proceso de validación y, en todo caso dejar para más tarde las validaciones, o al menos, que se encuentren en un lugar qu las haga flexible. Veamos un ejemplo. Ejemplo 1
   1:  public class Persona
   2:  {
   3:      private int _edad;
   4:      private string _nombre;
   5:      private string _apellido;
   6:      private string _email;
   7:   
   8:      public string Email
   9:      {
  10:          get { return _email; }
  11:          set { _email = value; }
  12:      }
  13:      public string Apellido
  14:      {
  15:          get { return _apellido; }
  16:          set { _apellido = value; }
  17:      }
  18:      public string Nombre
  19:      {
  20:          get { return _nombre; }
  21:          set { _nombre = value; }
  22:      }
  23:      public int Edad
  24:      {
  25:          get { return _edad; }
  26:          set { _edad = value; }
  27:      }
  28:  }
Ok, supongan que queremos validar lo siguiente:

  • Que el nombre no sea nulo
  • Que tenga entre 4 y 20 caracteres
  • El apellido igual
  • La edad que sea mayor de 18
  • Y el mail correctamente formado

Si, no es muy difícil, pero lo hacemos con algunos método o qué se yo y después las reglas cambian, hay que buscar por todo el código, es más, si llegamos a utilizar esta entidad en varios proyectos (desde varios assembies quiero decir) se pone medio feo, porque tenemos que tener las reglas de validación públicas, en fin.

Cómo se hace con VAP, bueno hay tres modos, por atributos, por configuración o ambos.

Validacion por atributos

Existe una serie de atributos para realizar las validaciones con VAP se encuentran en Microsoft.Practices.EnterpriseLibrary.Validation.Validators, hay muchos (me da un poco de fiaca escribirlos) pero les aseguro que hay para todos los gusto, y es más, podemos escribir los propios, eso lo vamos a ver más adelante. Veamos como decoramos nuestra clase Persona con los atributos.

   1:          public class Persona
   2:          {
   3:              [RegexValidator(@"^[a-zA-Z][\w\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$", MessageTemplate = "El email no es válido")]
   4:              public string Email
   5:              {
   6:                  get { return _email; }
   7:                  set { _email = value; }
   8:              }
   9:   
  10:              [NotNullValidator(MessageTemplate = "El apellido no puedo estar vacío")]
  11:              [StringLengthValidator(4, 20, MessageTemplate = "El largo del mensaje debe estar en 4 y 20 caracteres")]
  12:              public string Apellido
  13:              {
  14:                  get { return _apellido; }
  15:                  set { _apellido = value; }
  16:              }
  17:   
  18:              [NotNullValidator(MessageTemplate = "El nombre no puedo estar vacío")]
  19:              [StringLengthValidator(4, 20, MessageTemplate = "El largo del mensaje debe estar en 4 y 20 caracteres")]
  20:              public string Nombre
  21:              {
  22:                  get { return _nombre; }
  23:                  set { _nombre = value; }
  24:              }
  25:   
  26:              [RangeValidator(18, RangeBoundaryType.Inclusive, 90, RangeBoundaryType.Inclusive)]
  27:              public int Edad
  28:              {
  29:                  get { return _edad; }
  30:                  set { _edad = value; }
  31:              }
  32:          }
  33:          public void Validar()
  34:          {
  35:              ValidationResults results = ValidationFactory.CreateValidator().Validate(p);
  36:              if (!results.IsValid)
  37:              {
  38:                  StringBuilder sb = new StringBuilder("Errores de validación");
  39:                  sb.AppendLine();
  40:   
  41:                  foreach (ValidationResult result in results)
  42:                  {
  43:                      sb.AppendLine(result.Message);
  44:                  }
  45:                  Console.WriteLine(sb.ToString());
  46:              }
  47:              else
  48:              {
  49:                  Console.WriteLine("todo bien");
  50:              }
  51:   
  52:          }

Listo, si lo corremos vemos que funciona de maravillas, una belleza. Pero esperen, no me digan "tengo que poner el código en el programa igual", esto es cierto, si bien ahora las validaciones son propias de la clase, no andan desperdigadas por ahí, pero esto no es lo mejor, lo mejor es que podemos prescindir de escribir ni un sólo atributo en las clases y poner las reglas de validación en el archivo de configuración de la aplicación. Pero eso lo vemos mañana, hasta entonces.