Ejemplo Validación con Enterprise Library en aplicación Windows

 
Hola a tod@s,
 
En el siguiente artículo expongo con un ejemplo muy sencillo como implementar en una aplicación de escritorio validaciones con las Enterprise Library de Microsoft (versión 3.1 Mayo 2007). El ejemplo está hecho en C# y os podéis bajar el código fuente aquí.
 
Creamos un nuevo proyecto de Windows Application, en mi caso lo he llamado ELValidation. Le añadimos las referencias de Microsoft.Practices.EnterpriseLibrary.Common, Microsoft.Practices.EnterpriseLibrary.Validation y Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WinForms.
 
En el ejemplo que he creado tengo una clase que representa a un empleado ("Employee.cs"), en la que defino sus propiedades. Es aquí donde mediante atributos en las propiedades le vamos asignando las validaciones.
 
        private string code;
        private string nif;
        private string firstName;
        private string lastName;
        private DateTime dateOfBirth;
        private string email;

        [StringLengthValidator(1, 10, Ruleset = "RuleSet1", MessageTemplateResourceName="InvalidCodeMessage", MessageTemplateResourceType=typeof(Resource1))]
        public virtual string Code
        {
            get { return code; }
            set { code = value; }
        }
        [NifValidator(Ruleset = "RuleSet1", MessageTemplateResourceName="InvalidNifMessage", MessageTemplateResourceType=typeof(Resource1))]
        public virtual string Nif
        {
            get { return nif; }
            set { nif = value; }
        }

        [RelativeDateTimeValidator(-120, DateTimeUnit.Year, -16, DateTimeUnit.Year, Ruleset = "RuleSet1", MessageTemplateResourceName = "InvalidBirthMessage", MessageTemplateResourceType = typeof(Resource1))]
        public DateTime DateOfBirth
        {
            get { return dateOfBirth; }
            set { dateOfBirth = value; }
        }

        [ValidatorComposition(CompositionType.And, Ruleset = "RuleSet1")]
        [RegexValidator(@"\w+([-+.’]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*", MessageTemplateResourceName = "InvalidEmailMessage2", MessageTemplateResourceType = typeof(Resource1), Ruleset = "RuleSet1")]
        [StringLengthValidator(1, 100, Ruleset = "RuleSet1", MessageTemplateResourceName = "InvalidEmailMessage1", MessageTemplateResourceType = typeof(Resource1))]
        public string Email
        {
            get { return email; }
            set { email = value; }
        }

Como podemos observar en el código, tengo varios tipos de validaciones, para la propiedad Code tengo la validación de que no sea vacía, para el NIF tengo una validación customizada que mas tarde explicaré como hacer, para la edad tengo una validación de fechas y por último, una múltiple validación. Además en este ejemplo he incorporado globalización para que el mensaje de la validación esté en varios idiomas.

En el atributo StringLengthValidator hay que pasar como parámetros un mínimo, un máximo, el conjunto de reglas que sigue y el mensaje, si no tuvieramos multi-idioma bastaría con poner MessageTemplate = "Lo que sea"

Para los validadores customizados hay que crearse dos clases, una que herede de Validator<T> y otra que herede de ValidatorAttribute, en mi ejemplo NifValidator.cs y NifValidatorAttribute.cs.

Éste sería el código de la clase que hereda del validatorAttribute en mi ejemplo:

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Practices.EnterpriseLibrary.Validation;
using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;

namespace ELValidation
{
    [AttributeUsage(AttributeTargets.All)]
    public class NifValidatorAttribute : ValidatorAttribute

    {
        public NifValidatorAttribute()
        {
        }

        protected override Validator DoCreateValidator(Type targetType)
        {
            return new NifValidator();
        }
    }
}

Y el código de la clase donde se hacen las validaciones:

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Practices.EnterpriseLibrary.Validation;
using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Validation.Configuration;
using System.Collections.Specialized;

namespace ELValidation
{
    [ConfigurationElementType(typeof(CustomValidatorData))]
    public class NifValidator : Validator<string>
    {

        public NifValidator() : base(null, null)
        {
        }

        public NifValidator(string nif, string messageTemplate)
            : this(nif, messageTemplate, null)
        {
        }

        public NifValidator(string nif, string messageTemplate, string tag)
            : base(messageTemplate, tag)
        {
        }

        protected override void DoValidate(string objectToValidate, object currentTarget, string key, Microsoft.Practices.EnterpriseLibrary.Validation.ValidationResults validationResults)
        {
            if (objectToValidate.Length > 1)
            {
                if (!ValidateNIF(objectToValidate.ToUpper()))
                {
                    string message = string.Format(this.MessageTemplate, objectToValidate);
                    this.LogValidationResult(validationResults, message, currentTarget, key);
                }
            }
            else
            {
                string message = string.Format(this.MessageTemplate, objectToValidate);
                this.LogValidationResult(validationResults, message, currentTarget, key);
            }
        }

        protected override string DefaultMessageTemplate
        {
            get { return "El NIF no es válido"; }
        }

        private bool ValidateNIF(string vNif)
        {
            string aux = string.Empty;
            int result;
            aux = vNif.Substring(0, vNif.Length – 1);

            if (aux.Length >= 7 && int.TryParse(aux, out result))
            {
                aux += letra_nif(Convert.ToUInt32(aux));
            }
            else
            {
                return false;
            }

            if (vNif == aux)
            {
                return true;
            }

            return false;

        }

        public string letra_nif(UInt32 dni)
        {
            string s_letra = "TRWAGMYFPDXBNJZSQVHLCKE";
            dni = dni % 23;
            s_letra = s_letra[Convert.ToInt16(dni)].ToString();
            return s_letra;
        }
    }
}

Ahora podemos crear un formulario para aplicar la validación:

Tenemos que agregar un errorProvider y un ValidationProvider, éste último no se encuentra en la barra de herramientas por defecto, yo me he creado una nueva pestaña y lo he agregado

En las propiedades del ValidationProvider debemos asociarle el errorProvider, decirle que conjunto de reglas debe seguir en la propiedad RuleSetName, en mi caso RuleSet1 y muy importante la propiedad SourceTypeName que será el NameSpace.Clase, NameSpace, en mi caso "ELValidation.Employee, ELValidation".

Luego en cada textbox nos aparece en sus propiedades una nueva categoria que es Validation donde encontraremos 3 propiedades por cada ValidationProvider que tengamos en el formulario. En mi caso tengo PerformValidation on vpEmployee = true, SourcePropertyName on vpEmployee = Code (nombre de la propiedad de la clase Employee que asocio al textbox y que quiero validar) y por último ValidatedProperty on vpEmployee = Text (aquí ira la propiedad del textbox que queremos validar, en este caso text, si fuera un datetimepicker sería value).

Y por último, en el evento Load del formulario podemos definir un objeto de tipo empleado, cuyas propiedades se recojan de los textbox del formulario. Y mediante un botón validarlo, de tal manera que la propiedad del ValidationProvider sea true y luego llamar a ValidateChildren del formulario.

Para que sea multi-idioma el mensaje que muestra el errorprovider basta con crearse los ficheros de recursos oportunos y luego asociarlo a los atributos de las propiedades que queremos validar con MessageTemplateResourceName = "InvalidBirthMessage", MessageTemplateResourceType = typeof(Resource1), en este caso le estaríamos indicando que el mensaje de validación está en el recurso llamado Resource1 y que hace referencia a InvalidBirthMessage.

Otra cosa importante que he visto, es que cuando tenemos una clase que hereda de otra que tiene validación, las propiedades que no se sobreescriben siguen teniendo la validación del padre, sin embargo las que se sobreescriben la pierden. En el ejemplo que he hecho lo podréis comprobar en la clase Boss que hereda de Employee.

Espero que os haya ayudado este artículo.

Saludos.

 

3 Responses to Ejemplo Validación con Enterprise Library en aplicación Windows

  1. Augusto Josué dice:

    Me ha parecido muy útil tu artículo

  2. Augusto Josué dice:

    Hola Carmen.Me gustaría hacerte una pregunta referente a tu ejemplo.Luego de asignarle los valores de las propiedades del control ValidationProvider y a los texbox, ocurre un error:"Excepción Inválida de Operación" -> "El tipo de fuente no representa un tipo de dato válido para el validation provider"Basicamente mi demo tiene funcionalidades parecidas a tu ejemplo, aunque yo no tengo multiidioma, ni asigno reglas (ruleset); me funciona al implementarlo en una app web, pero no en una app winforms.cedenoaugusto@gmail.com

  3. rafa dice:

    muy bueno, muchas gracias

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: