2010-08-01 13 views
9

Quiero extender los validadores asp.net de modo que pueda hacer que un validador dependa de otro. La situación que tengo es que tenemos que validar una fecha en un cuadro de texto. Normalmente solo usaría una combinación de RequiredFieldValidator (para garantizar que se proporcione la fecha), CompareValidator (para garantizar que la fecha sea una fecha) y finalmente un RangeValidator (para asegurar que la fecha esté dentro del límite requerido).Extendiendo validadores ASP.NET

El problema con esto es que los validadores no dependen entre sí, por lo que el usuario verá posiblemente los tres mensajes a la vez para cada validador cuando realmente todo lo que queremos que vea sea el mensaje más relevante, es decir, si ingresaron "abc" en el cuadro de texto de la fecha, no sería apropiado mostrarles el mensaje diciendo que la fecha no estaba en el rango válido (aunque técnicamente supongo que esto es cierto).

Actualmente, para proporcionar este tipo de funcionalidad utilizamos un CustomValidator y simplemente colocamos las tres validaciones dentro del servidor validar el controlador de eventos y cambiamos el mensaje de error programáticamente dependiendo de qué validación falló.

Me gustaría estandarizar esto un poco más, ya que ocurre bastante en esta aplicación, me imagino que si puedo hacer que los validadores sean dependientes uno del otro, esto resolverá el problema y también nos permitirá utilizar el cliente Validación lateral en lugar de tener que hacer una devolución de datos especialmente para manejar la validación personalizada.

La idea es que si un validador depende de otro si ese "maestro" es válido, entonces el dependiente realizará su validación normal (EvaluateIsValid()); de lo contrario, si el validador maestro no es válido, entonces los otros validadores dependientes serán válido.

He obtenido la siguiente solución al heredar de los diversos controles de validador que ya se han proporcionado en el marco.

public class RequiredFieldDependentValidator : RequiredFieldValidator 
{ 
    [Description("The validation control to depend on for determining if validation should occur")] 
    public string ValidationControlToDependOn 
    { 
     get 
     { 
      object obj = ViewState["ValidationControlToDependOn"]; 
      if (obj != null) return (string) obj; 
      return null; 
     } 
     set 
     { 
      Control control = FindControl(value); 
      if (control is IValidator) 
       ViewState["ValidationControlToDependOn"] = value; 
      else 
       throw new HttpException("ValidationControlToDependOn is not a validation control"); 
     } 
    } 

    protected override bool EvaluateIsValid() 
    { 
     IValidator validationControlToDependOn = FindControl(ValidationControlToDependOn) as IValidator; 

     if(validationControlToDependOn != null) 
     { 
      return !validationControlToDependOn.IsValid || base.EvaluateIsValid(); 
     } 

     return base.EvaluateIsValid(); 
    } 

Actualmente acabo han codificado por el RequiredFieldValidator, idealmente me gustaría proporcionar esta funcionalidad para todos los validadores, pero no puedo ver una manera de hacer esto sin necesidad de copiar el código anterior en una clase similar para cada tipo de validador individual Deseo proporcionar esta funcionalidad, por lo tanto, si hay algún problema, tendré que volver atrás y cambiar este código en cada tipo de validador de forma individual.

¿Hay alguna manera de "centralizar" este código y tenerlo fácilmente utilizado en los validadores sin tener que escribir todos los validadores desde cero para poder cambiar la clase que heredan de más adelante en la línea.

Saludos,

Respuesta

0

Es posible que desee buscar en un WebControlAdapter.

Básicamente le permite anular ciertos métodos de controles web (condicionalmente para algunos navegadores si es necesario, pero aquí puede ser para todos).

En su caso, desea anular el método EvaluateIsValid y comprobar si el control tiene alguna dependencia de un validador "principal".

Como ejemplo, un adaptador TextBox que creamos recientemente para representar un atributo 'maxlength' para el control.

Public Class TextBoxAdapter 
     Inherits WebControlAdapter 

     Private ReadOnly Property TextBoxControl() As TextBox 
      Get 
       Return DirectCast(MyBase.Control, TextBox) 
      End Get 
     End Property 

     Protected Overrides Sub RenderBeginTag(ByVal writer As System.Web.UI.HtmlTextWriter) 
      If TextBoxControl.TextMode = TextBoxMode.MultiLine AndAlso TextBoxControl.MaxLength > 0 Then 
       writer.AddAttribute("maxlength", TextBoxControl.MaxLength.ToString) 
      End If 

      MyBase.RenderBeginTag(writer) 
     End Sub 
    End Class 

Para usarlo, basta con crear un archivo en el directorio de .browser App_Browsers y configurar el adaptador de ahí:

<browsers> 
    <browser refID="Default"> 
     <controlAdapters> 
      <adapter controlType="System.Web.UI.WebControls.TextBox" 
       adapterType="TextBoxAdapter" /> 
     </controlAdapters> 
    </browser> 
</browsers> 

La única complicación que aún permanece en su caso es cómo almacenar el validador dependientes para que EvaluateIsValid tenga acceso a este directorio. Puede considerar un control no renderizado como Onof sugerido o bien Viewstate/Cookie/otro mecanismo de almacenamiento.

1

usted podría reemplazar el método Validar en el que la base página. Para añadir la información de dependencia de validación en la página se puede implementar un control sin fundir:

<my:ValidationDependency TargetControl="RegExp1" Dependency="Required1" /> 
0

puede tener ValidationControlToDependOn propiedad a partir del tipo de lista y añadir los validadores en la lista. Entonces podemos suponer que el validador agregado más tarde depende del validador agregado antes.

por lo que su protected override bool EvaluateIsValid()

va a cambiar un poco

foreach(IValidator validator in ValidationControlToDependOn) 
{ 
return !validator.IsValid; 

} 
+0

¿no haría eso que cada validador de la página dependiera del anterior? Y creo que aún necesitaría la subclase de cada validador –

0

Estoy buscando en los extensores de control que parece que podría ser prometedora, pero no puedo encontrar muchos ejemplos de hacer nada, pero AJAX cosas con él.

+0

Lo intenté, pero no puede anular un método del control extendido. OMI, la única forma de evitar la creación de subclases es anular la página. Validar(). – onof