Permitir la validación de un control con los validadores estándar de ASP.NET

Tal y como prometí en un anterior post, voy a explicar cómo podemos conseguir que un control sea utilizable directamente por los controles de validación estándar que vienen con ASP.NET.


Ciertos controles Web (por ejemplo el control Calendar) no permiten su uso combinado con los controles de validación (estilo RequiredFieldValidator, RangeValidator, etc…), lo cual es una lástima porque para poder validar su contenido tenemos que construir nuestro propio control de validación (en fin…) o bien usar eventos de servidor para poder validarlos. Una de las ventajas de los controles de validación de ASP.NET es que ya realizan una validación en el cliente además de la que se hace en el servidor después, lo que ahorra tiempo y agiliza mucho la interfaz. Además están integrados en la validación de la página y permiten comprobar la propiedad IsValid de ésta antes de continuar con suprocesamiento, algo muy útil también.


Por otro lado es muy habitual combinar diversos controles Web con una propósito común dentro de un control de usuario (.ascx) de forma que podamos reutilizarlos en cualquier lugar de la interfaz. Al igual que (como hemos visto), por defecto, no tienen un método para establecer su foco, tampoco es posible usarlos con los validadores estándar, por lo que pierden parte de su utilidad al no poder usarlos del mismo modo que los controles más habituales.


Sería interesante poder añadir la capacidad de trabajar con los controles de validación a este tipo de controles. Vamos a ver cómo conseguirlo.


Un ejemplo real


Por ejemplo, imagina un control ASCX de selección específico de nuestra aplicación. Éste contiene un par de listas desplegables para seleccionar elementos desde la base de datos, una lista de elementos vacía inicialmente y un botón que permite añadir elementos a esta lista para su selección. Queremos colocar este control en cualquier formulario y que nos sirva, por ejemplo, para seleccionar localidades de un país. Su aspecto sería similar a este:



Este control de la imagen es uno real, usado en diversos lugares de la aplicación de uno de nuestros clientes para permitir la selección de zonas y áreas geográficas relacionadas. Tiene una funcionalidad relativamente compleja que implica el uso de bases de datos, validación de los datos seleccionados, etc… En algunos lugares de la aplicación se permite su uso de forma que no es obligatoria la selección de elementos (por ejemplo para las búsquedas, ya que si no se indica zona alguna no se restringe por dicha dimensión), y en otras zonas es necesario validar que se haya seleccionado como mínimo una zona, o incluso más de una.


Con el control creado de la manera habitual, al colocarlo en un formulario no podemos utilizar los controles de validación con él, por lo que no nos quedaría más remedio que responder a un evento de servidor (por ejemplo a la pulsación del botón de la acción principal del formulario), hacer la comprobación pertinente y mostrar un mensaje en el cliente con una etiqueta, con lo que no se integraría con la validación de los restantes controles.


Añadiendo la funcionalidad de validación


Para que un control pueda ser validado por un validador común debe implementar alguna propiedad de tipo texto que devuelva un valor interpretable por el validador. Normalmente deberíamos hacer que devolviera una cadena vacía en caso de no contener un valor correcto y así funcionará bien con el RequiredFieldValidator.


En nuestro caso hemos definido la propiedad NumItems del control ASCX que simplemente indica el número de zonas seleccionadas en el control en un momento dado:


public string NumItems
{
  get 
  {
    if (lstSeleccion.Items.Count > 0)
      return lstSeleccion.Items.Count.ToString();
    else
      return String.Empty;
    }
}


Una vez definida esta propiedad debemos indicar al runtime de ASP.NET que será ésta la utilizada para realizar las validaciones. ello se consigue usando el atributo ValidationProperty. Éste toma como parámetro el nombre de la propiedad a utilziar en las validaciones, por lo que en la definición de nuestra clase escribimos:


[ValidationProperty(«NumItems»), SupportsEventValidation]
public partial class Controles_SelectorZonas : System.Web.UI.
UserControl
{



Así indicamos que los validadores deben usar la propiedad NumItems para realizar la validación. El otro atributo, SupportsEventValidation, se utiliza para indicar al runtime que nuestro control soporta los eventos de validación ya qe de otra forma no se generarían eventos de validación.


Nota: Si quisiésemos hacer algo similar con un control estándar que no soporte validación, como el calendario, tendríamos que crear una nueva clase que heredara de éste y decorarla con este atributo para poder usarlo.


Vale. Listo. Si ahora soltamos el control en un formulario Web y añadimos un control de validación veremos que… ¡no aparece nuestro control en la lista de los controles que podenmos utilizar! 🙁


No pasa nada. Es un pequeño efecto secundario. Simplemente añadámoslo a mano en el atributo ControlToValidate del validador y veremos que funciona correctamente. Por ejemplo:



<asp:RequiredFieldValidator ID=»RequiredFieldValidator1″ runat=»server» ControlToValidate=»lstDestinos»
CssClass=»ErrorMsg» Display=»Dynamic» ErrorMessage=»Debe seleccionar al menos una zona de destino.»></asp:RequiredFieldValidator>


El valor del atributo ControlToValidate, que es el nombre del control ascx que queremos validar, lo hemos metido a mano, pero funciona  perfectamente que es lo que buscábamos. Ahora nuestro complejo control de usuario se integra bien en la estructura de validación de la pa´gina y podemos trabajar con él como con cualquier otro control validable.


Super-útil ¿no? 🙂

Sin categoría

8 thoughts on “Permitir la validación de un control con los validadores estándar de ASP.NET

  1. Hola:

    borra la carpeta temporal de tu proyecto en

    C:WindowsMicrosoft.NETFrameworkv2.0.xxxxxxTemporary ASP.NET Files

    y supongo que problema resuelto…

  2. Hola, estoy dando mis primeros pasos en ASP.NET y me gustaria hacerte un par de preguntas si no es molestia:
    * en un detailsView….se pueden utilizar controles como por ejemplo un DropDownList?????.
    * Se pueden utilizar controles de validacion de los campos del detailsView???
    * Tendras sin compromiso algun ejemplo de codigo de un ABM en ASP.NET???
    Te paso mi correo: arrobalabase@hotmail.com

    Muchas gracias!!

  3. Hola disculpa para pedirte un favor estoy haciendo mi proyecto de residencia en Expression web, es un sistema de consultas, altas , bajas, ediciony otros detalles.
    El problema que tengo es en la ventana de altas, al ingresar un nuevo registro me funciona perfectamente y lo almacena en la base de datos, lo malo es que si ingreso una clave que ya existe pues se duplica el registro y me truena el sistema.
    Me podrias decir como le hago para evitar la insercion de valores duplicados. Porfavor seria una grandisima ayuda. Gracias. Mi correo es yamir_spencer@hotmail.com

  4. hola otra vez yo, el problema de valores duplicados ya lo resolvi. Ojala y me pudieras ayudar en el siguiente problema:
    Estoy realizando una pagina en expression web. y utilizando sql server 2005 al momento que doy click en un boton me despliegue los datos de una consulta te agradeceria mucho tu ayuda

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *