2008-10-30 10 views
4

J'utilise Asp.Net 2.0. J'ai un scénario où je dois vérifier une entrée d'utilisateur contre l'une de deux gammes. Par exemple Je dois vérifier une valeur de zone de texte par rapport aux plages 100-200 ou 500-600. Je sais que je peux raccorder 2 Range.Validators Asp.Net à la TextBox, mais cela va essayer de valider l'entrée contre les deux plages, une condition ET, si vous voulez. CustomValidator est une option, mais comment puis-je passer les 2 valeurs de plages du côté serveur. Est-il possible d'étendre le RangeValidator pour résoudre ce problème particulier?Asp.Net: Validation de plage étendue

[Mise à jour] Désolé je n'ai pas mentionné ceci, le problème pour moi est que la gamme peut varier. Et aussi les différents contrôles dans la page auront différentes plages basées sur certaines conditions. Je sais que je peux tenir ces valeurs dans certains éléments d'entrée variables ou masqués, mais cela ne sera pas très élégant.

Répondre

0

J'ai étendu le BaseValidator pour y parvenir. C'est assez simple une fois que vous comprenez comment fonctionnent les validateurs. J'ai inclus une version brute du code pour montrer comment cela peut être fait. Rappelez-vous qu'il est adapté à mon problème (comme int devrait toujours être> 0), mais vous pouvez facilement l'étendre.

public class RangeValidatorEx : BaseValidator 
{ 

    protected override void AddAttributesToRender(System.Web.UI.HtmlTextWriter writer) 
    { 
     base.AddAttributesToRender(writer); 

     if (base.RenderUplevel) 
     { 
      string clientId = this.ClientID; 

      // The attribute evaluation funciton holds the name of client-side js function. 
      Page.ClientScript.RegisterExpandoAttribute(clientId, "evaluationfunction", "RangeValidatorEx"); 

      Page.ClientScript.RegisterExpandoAttribute(clientId, "Range1High", this.Range1High.ToString()); 
      Page.ClientScript.RegisterExpandoAttribute(clientId, "Range2High", this.Range2High.ToString()); 
      Page.ClientScript.RegisterExpandoAttribute(clientId, "Range1Low", this.Range1Low.ToString()); 
      Page.ClientScript.RegisterExpandoAttribute(clientId, "Range2Low", this.Range2Low.ToString()); 

     } 
    } 

    // Will be invoked to validate the parameters 
    protected override bool ControlPropertiesValid() 
    { 
     if ((Range1High <= 0) || (this.Range1Low <= 0) || (this.Range2High <= 0) || (this.Range2Low <= 0)) 
      throw new HttpException("The range values cannot be less than zero"); 

     return base.ControlPropertiesValid(); 
    } 

    // used to validation on server-side 
    protected override bool EvaluateIsValid() 
    { 
     int code; 
     if (!Int32.TryParse(base.GetControlValidationValue(ControlToValidate), out code)) 
      return false; 

     if ((code < this.Range1High && code > this.Range1Low) || (code < this.Range2High && code > this.Range2Low)) 
      return true; 
     else 
      return false; 
    } 

    // inject the client-side script to page 
    protected override void OnPreRender(EventArgs e) 
    { 
      base.OnPreRender(e); 

      if (base.RenderUplevel) 
      { 
       this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "RangeValidatorEx", RangeValidatorExJs(),true); 
      } 
    } 


    string RangeValidatorExJs() 
    { 
     string js; 
     // the validator will be rendered as a SPAN tag on the client-side and it will passed to the validation function. 
     js = "function RangeValidatorEx(val){ " 
     + " var code=document.getElementById(val.controltovalidate).value; " 
     + " if ((code < rangeValidatorCtrl.Range1High && code > rangeValidatorCtrl.Range1Low) || (code < rangeValidatorCtrl.Range2High && code > rangeValidatorCtrl.Range2Low)) return true; else return false;}"; 
     return js; 
    } 


    public int Range1Low 
    { 
     get { 
      object obj2 = this.ViewState["Range1Low"]; 

      if (obj2 != null) 
       return System.Convert.ToInt32(obj2); 

      return 0; 

     } 
     set { this.ViewState["Range1Low"] = value; } 
    } 

    public int Range1High 
    { 
     get 
     { 
      object obj2 = this.ViewState["Range1High"]; 

      if (obj2 != null) 
       return System.Convert.ToInt32(obj2); 

      return 0; 

     } 
     set { this.ViewState["Range1High"] = value; } 
    } 
    public int Range2Low 
    { 
     get 
     { 
      object obj2 = this.ViewState["Range2Low"]; 

      if (obj2 != null) 
       return System.Convert.ToInt32(obj2); 

      return 0; 

     } 
     set { this.ViewState["Range2Low"] = value; } 
    } 
    public int Range2High 
    { 
     get 
     { 
      object obj2 = this.ViewState["Range2High"]; 

      if (obj2 != null) 
       return System.Convert.ToInt32(obj2); 

      return 0; 

     } 
     set { this.ViewState["Range2High"] = value; } 
    } 
} 
+0

Vous pouvez vouloir vérifier IsClientScriptRegistered avant d'appeler RegisterScriptBlock .. – HashName

1

Vous pouvez utiliser le RegularExpressionValidator avec l'ensemble de la propriété ValidationExpression à

Edit: (oups, 650 et 201, etc. étaient valides avec l'ancien modèle)

^(1\d{2}|200|5\d{2}|600)$ 

Cela permettra de tester le texte saisi pour 100-200 et 500-600.

+0

Ceci est une solution beaucoup plus élégante. Bien joué. Je suis terrible avec les expressions régulières. –

+0

Je ne suis pas très bon avec eux non plus, mais cela ne correspond pas aussi 299 et 650, qui sont en dehors de la plage? – korro

+0

Oui, c'est le cas. Je me sens beaucoup mieux sur ma propre réponse maintenant :) –

1

Je ne crois pas que ce soit possible en utilisant le contrôle RangeValidator standard. J'ai fait quelques recherches et je crois que votre meilleure solution va être de créer votre propre contrôle CustomValidator que vous pouvez inclure dans votre projet pour gérer ce scénario.

http://www.dotnetjunkies.ddj.com/Article/592CE980-FB7E-4DF7-9AC1-FDD572776680.dcik

Vous ne devriez pas avoir à compiler juste pour l'utiliser dans votre projet, aussi longtemps que vous faites référence correctement.

4

Un CustomValidator devrait fonctionner. Je ne suis pas sûr de ce que vous entendez par "passer les valeurs des deux gammes du côté serveur". Vous pouvez valider sur le côté serveur en utilisant une méthode de validation comme ceci:

void ValidateRange(object sender, ServerValidateEventArgs e) 
{ 
    int input; 
    bool parseOk = int.TryParse(e.Value, out input); 
    e.IsValid = parseOk && 
       ((input >= 100 || input <= 200) || 
       (input >= 500 || input <= 600)); 
} 

Vous devrez alors définir la propriété OnServerValidate de votre CustomValidator à « ValidateRange », ou tout ce que vous arrive d'appeler.

Est-ce le genre de chose que vous recherchez?