Ausführliche Beschreibung der Validierung in ASP+

Veröffentlicht: 08. Dez 2000 | Aktualisiert: 17. Jun 2004

Von Anthony Moore

Dieser Artikel enthält eine ausführliche Beschreibung der Steuerelemente zur Validierung von Webanwendungen in ASP+.

* * *

Auf dieser Seite

Einführung Einführung
Vorgeschichte Vorgeschichte
 Was geschieht wann?  Was geschieht wann?
Serverseitige Validierungssequenz Serverseitige Validierungssequenz
Clientseitige Validierung Clientseitige Validierung
Gültigkeitsregeln und verständliche Fehlermeldungen Gültigkeitsregeln und verständliche Fehlermeldungen
 Auswirkungen der Eigenschaften "Enabled", "Visible" und "Display"  Auswirkungen der Eigenschaften "Enabled", "Visible" und "Display"
 Das "CustomValidator"-Steuerelement  Das "CustomValidator"-Steuerelement
 Welche Steuerelemente lassen sich überprüfen?  Welche Steuerelemente lassen sich überprüfen?
 Zu guter Letzt  Zu guter Letzt

Einführung

Dieser Artikel behandelt ausführlich die Funktionsweise der Validierungssteuerelemente in ASP+ und richtet sich besonders an Programmierer, die mit Hilfe von Validierungssteuerelementen komplexe Seiten erstellen oder das Validierungsframework erweitern möchten. Anfänger sollten zunächst den Artikel Gültigkeitsprüfung der Benutzereingabe in ASP+ lesen.

 

Vorgeschichte

Bei der Entwicklung von ASP+ war uns die Bedeutung einer Validierung stets bewusst. Beim Betrachten der meisten heutigen kommerziellen Websites fällt auf, dass dort viele Formulare enthalten sind, die jede Menge handgeschriebenen Code zur Durchführung der Validierung ausführen. Das Schreiben dieses Codes ist alles andere als eine spannende Angelegenheit. Es macht Spaß, den Code zum Anzeigen von Tabellen oder Daten oder zum dynamischen Generieren von Diagrammen zu schreiben, aber dass ein Benutzer bei der Eingabe eines ungültigen Wertes in einem Namensfeld gestoppt wird, kann niemanden so recht begeistern.

Die Validierung von Webanwendungen gestaltet sich auch aus anderen Gründen als recht frustrierend. HTML 3.2 ist im Hinblick auf Kontrolle und Benutzerfeedback so eingeschränkt, dass Sie nicht dieselben Funktionen wie für leistungsstärkere Clients anwenden können, beispielsweise das Verhindern der Eingabe bestimmter Zeichen oder die Ausgabe von Signaltönen. Eine effizientere Validierung kann unter Verwendung von Browserskripts erstellt werden, was jedoch nicht so einfach umzusetzen ist, da Skripts in Clientbrowsern nicht immer vorhanden sind und von bösartigen Benutzern vorsätzlich umgangen werden können. Um die Sicherheit der Site zu gewährleisten, müssen daher dieselben Überprüfungen ohnehin auch auf dem Server implementiert werden.

Bei der Entwicklung von ASP+ hatten wir ursprünglich beabsichtigt, nur ein Steuerelement bei der Validierung zu verwenden. Es handelte sich dabei um eine Version des TextBox-Steuerelements, mit dem sich auch Anzeigefehler kontrollieren lassen. Als es an die Entwicklung des Steuerelements ging, stellte sich dieses Konzept jedoch als nicht besonders geeignet heraus. Auf der Suche nach einer Lösung, die sich auf so viele Formulare wie möglich anwenden lässt, untersuchten wir unzählige Dateneingabeformulare und kamen dabei zu folgenden interessanten Ergebnissen:

  • In der Regel werden Fehlermeldungen oder Symbole neben den Eingabeelementen angezeigt, befinden sich jedoch fast immer in verschiedenen Tabellenzellen.

  • In der Regel gibt es einen Bereich auf der Seite, in dem alle Fehler zusammengefasst werden.

  • Viele Sites enthalten Clientskripts, um mehr unmittelbares Feedback erhalten zu können und unnötige Roundtrips zum Server zu vermeiden.

  • Viele Sites, in denen Clientskripts verwendet werden, zeigen bei Fehlern entsprechende Fehlertextfelder an.

  • Neben Texteingaben werden oftmals auch Dropdownlisten und Optionsschaltflächen überprüft.

  • Bleibt ein Feld leer, blenden Sites i.d.R. eine andere Meldung oder ein anderes Symbol ein, als bei gültigen Eingaben angezeigt wird.

  • Viele Gültigkeitsüberprüfungen eignen sich hervorragend für reguläre Ausdrücke.

  • Die Gültigkeit hängt i.d.R. vom Vergleich von Eingaben ab.

  • Die Tasks der Validierung bestehen zu mindestens 90 Prozent aus gängigen Operationen wie dem Überprüfen von Namen und Postleitzahlen. In den meisten Sites schien das Rad neu erfunden worden zu sein.

  • Im Allgemeinen sind die Sites zu unterschiedlich, so dass es keine hundertprozentige Lösung für die Validierung einer Site geben kann.

Unter Berücksichtigung dieser Ergebnisse haben wir uns für eine Lösung bestehend aus fünf Validator-Steuerelementen, dem ValidationSummary-Steuerelement und dem Page-Objekt entschieden. Außerdem musste die Lösung erweiterbar sein und eine API enthalten, um auf Clients und Servern gleichermaßen funktionieren zu können.

Bei der Untersuchung der unterschiedlichen Validierungstasks schien der Einsatz einer größeren Toolbox erforderlich zu sein. Bei den meisten Komponentenumgebungen wie Microsoft ActiveX hätten wir möglicherweise versucht, die Funktionen sämtlicher Validierungssteuerelemente auf ein einziges Steuerelement zu übertragen, das mit verschiedenen Eigenschaften in unterschiedlichen Modi hätte funktionieren sollen. Dank der Vererbungsmöglichkeiten im Microsoft .NET Framework ist es jedoch möglich, ein Paket von Steuerelementen mit speziellen Eigenschaften für spezielle Validierungen bereitzustellen, da der Aufwand für die Ableitung neuer Steuerelemente sehr gering ist.

Die meisten Funktionen dieser Steuerelemente sind in ihrem übergeordneten BaseValidator-Steuerelement implementiert. Sie können auch aus BaseValidator oder den anderen Steuerelementen ableiten, um dies zu nutzen. Selbst BaseValidator implementiert seine eigene Text-Eigenschaft nicht, sondern erbt diese von Label.

 

Was geschieht wann?

Es ist unabdingbar, die Abfolge von Ereignissen bei der Verarbeitung einer Seite mit Websteuerelementen zur Validierung zu verstehen. Sind einige Bedingungen der Validierung optional, müssen Sie genau wissen, wann die Prüfung jeweils auf dem Client und dem Server stattfindet. Wenn Sie Ihre eigenen Routinen zur Validierung schreiben, die zeitaufwendig sind und möglicherweise andere Auswirkungen haben, ist es ebenfalls wichtig zu wissen, wann sie aufgerufen werden.

Betrachten wir zunächst die Vorgänge auf dem Server.

 

Serverseitige Validierungssequenz

Grundlegende Voraussetzung ist das Verständnis des Lebenszyklus einer Seite. Für diejenigen, die bisher mit Formularen in Visual Basic oder ähnlichen leistungsstarken Clienttools gearbeitet haben, ist dies etwas gewöhnungsbedürftig, denn eine Seite und alle darin enthaltenen Objekte "leben" nicht für die Dauer ihrer Benutzerinteraktion, auch wenn es manchmal den Anschein haben mag.

Nachstehend sehen Sie einen vereinfachten Ablauf der Ereignisse beim ersten Zugriff auf eine Seite:

  1. Die Seite und ihre Steuerelemente werden auf Grundlage der ASPX-Datei erstellt.

  2. Das Page_Load-Ereignis wird ausgelöst.

  3. Die Eigenschaften der Seite und der Steuerelemente werden in einem verborgenen Feld gespeichert.

  4. Die Seite und die Steuerelemente werden in HTML konvertiert.

  5. Alles wird gelöscht.

Wenn ein Benutzer jetzt auf eine Schaltfläche oder ein ähnliches Steuerelement klickt, wird eine Verbindung zum Server hergestellt, auf dem dann eine ähnliche Sequenz, auch Zurückschreibesequenz (post-back sequence) genannt, ausgeführt wird:

  1. Die Seite und ihre Steuerelemente werden auf Grundlage der ASPX-Datei erstellt.

  2. Die im verborgenen Feld gespeicherten Eigenschaften der Seite und der Steuerelemente werden wiederhergestellt.

  3. Die Steuerelemente der Seite werden auf Grundlage der Benutzereingabe aktualisiert.

  4. Das Page_Load-Ereignis wird ausgelöst.

  5. Ereignisse mit der Benachrichtigung über die Änderung werden ausgelöst.

  6. Die Eigenschaften der Seite und der Steuerelemente werden in einem verborgenen Feld gespeichert.

  7. Die Seite und die Steuerelemente werden in HTML konvertiert.

  8. Alles wird erneut gelöscht.

Warum werden nicht einfach sämtliche Objekte gespeichert? Antwort: Websites, die mit ASP+ erstellt wurden, können nicht von einer großen Anzahl von Benutzern verwendet werden. Daher sind die einzigen Objekte, die auf dem Server gespeichert sind, Objekte, die jeweils in dem Moment verarbeitet werden.

Beim ersten Zugriff auf eine Seite findet erst einmal keine serverseitige Validierung statt. Da die meisten Endbenutzer sehr gewissenhaft sind, gehen wir zunächst davon aus, dass sie die Formulare richtig ausfüllen, und bombardieren sie nicht sofort mit roten Fehlermeldungen.

Beim Zurückschreiben wird die Validierung zwischen den Schritten 3 und 4 ausgeführt, d.h. direkt nach dem Laden der Eingabedaten des Benutzers in die Eigenschaften der Steuerelemente, jedoch vor Ausführen des Großteils des Codes. Wenn Sie also Benutzerereigniscode schreiben, können Sie i.Allg. davon ausgehen, dass die Validierung, wie zumeist gewünscht, bereits stattgefunden hat.

Der Nachteil bei dieser Methode ist jedoch, dass Sie Elemente, die bei der Validierung berücksichtigt und ausgewertet werden, erst zu spät ändern können. So könnten Sie beispielsweise feststellen, dass der von Ihnen geschriebene Code zum Aktivieren oder Deaktivieren von Validierungssteuerelementen oder zum Ändern ihrer Eigenschaften erst dann Auswirkungen zeigt, wenn die Seite das nächste Mal verarbeitet wird. Dieses Problem kann auf zwei Arten vermieden werden:

  • Ändern Sie die Eigenschaften, bevor die Validierung ausgeführt wird.

  • Lassen Sie die Steuerelemente erneut überprüfen, nachdem ihre Eigenschaften geändert wurden.

Für beide Vorgänge benötigen Sie die Validierungseigenschaften und -methoden des Page-Objekts.

Die API des "Page"-Objekts

Das Page-Objekt besitzt einige wichtige Eigenschaften und Methoden für die serverseitige Validierung. Eine Zusammenfassung finden Sie in Tabelle 1:

Tabelle 1: Eigenschaften und Methoden des "Page"-Objekts

Eigenschaft oder Methode

Beschreibung

IsValid-Eigenschaft

Dies ist die nützlichste Eigenschaft. Mit ihr können Sie die Gültigkeit des gesamten Formulars prüfen (i.d.R. vor der Aktualisierung der Datenbank). Sie gibt den Wert True nur dann aus, wenn alle Objekte in der Validators-Auflistung gültig sind. Der Wert wird nicht zwischengespeichert.

Validators-Eigenschaft

Eine Auflistung sämtlicher Validierungsobjekte einer Seite. Diese Objekte implementieren die IValidator-Schnittstelle.

Validate-Methode

Eine Methode, die zum Zeitpunkt der Validierung aufgerufen wird. Die Standardimplementierung im Page-Objekt fragt jeden Validator zur Selbstbewertung ab.

Die Validators-Auflistung ist eine Auflistung von Objekten, die die IValidator-Schnittstelle implementieren, und eignet sich zur Ausführung mehrerer Vorgänge. Ich verwende hier den Ausdruck Objekte anstelle von Steuerelementen, da sich das Page-Objekt nur mit der IValidator-Schnittstelle befasst. Da es sich bei allen Validatoren i.d.R. um visuelle Steuerelemente handelt, die die IValidator-Schnittstelle implementieren, kann jeder Entwickler der Seite ein beliebiges Validierungsobjekt hinzufügen.

Die IValidator-Schnittstelle besitzt folgende Eigenschaften und Methoden:

Tabelle 2: Eigenschaften und Methoden der "IValidator"-Schnittstelle

Eigenschaft oder Methode

Beschreibung

IsValid-Eigenschaft

Zeigt an, ob die Validierung der einzelnen Validierungsobjekte erfolgreich war. Im Anschluss an die Validierung können Sie diesen Wert manuell ändern.

ErrorMessage-Eigenschaft

Beschreibt den Fehler, den ein Validierungsobjekt derzeit prüft und der dem Benutzer u.U. angezeigt wird.

Validate-Methode

Führt die Validierung des Validierungsobjekts aus, um dessen IsValid-Wert zu aktualisieren.

Mit dieser Schnittstelle lassen sich einige interessante Vorgänge ausführen. Sie können beispielsweise eine Seite unter Verwendung des folgenden Codes (Beispiele in C#) auf einen gültigen Status zurücksetzen:

    IValidator val; 
    foreach(val in Validators) { 
        Val.IsValid = true; 
    } 

Verwenden Sie zur erneuten Ausführung der gesamten Validierungssequenz folgenden Code:

    IValidator val; 
    foreach(val in Validators) { 
        Val.Validate(); 
    } 

Wenn Sie mit der Beta 1-Version oder höher arbeiten, können Sie alternativ zum oben genannten Vorgang einfach die Validate-Methode im Page-Objekt aufrufen. Wenn Sie Änderungen vornehmen möchten, bevor die Validierung ausgeführt wird, haben Sie die Möglichkeit, die Validate-Methode außer Kraft zu setzen. Das folgende Beispiel zeigt eine Seite, die einen Validator enthält, der entsprechend dem Wert in einem Kontrollkästchen aktiviert bzw. deaktiviert wird:

    public class Conditional : Page { 
        public HtmlInputCheckBox chkSameAs; 
        public RequiredFieldValidator rfvalShipAddress; 
        protected override void Validate() { 
            // Versandadresse nur bei Abweichung von Rechnungsadresse prüfen 
            bool enableShip = !chkSameAs.Checked; 
            rfvalShipAddress.Enabled = enableShip; 
            // Validierung jetzt ausführen 
            base.Validate(); 
        } 
    } 

 

Clientseitige Validierung

Wenn die clientseitige Validierung für Ihre Seite aktiviert wird, findet eine gänzlich andere Abfolge zwischen den Roundtrips statt. Die clientseitige Validierung wird unter Verwendung von JScript ausgeführt und benötigt keine binären Komponenten.

Während die JScript-Sprache weitestgehend standardisiert ist, ist dies für das Dokumentobjektmodell (Document Object Model, DOM) zur Interaktion mit HTML-Dokumenten in Browsern nicht der Fall. Aus diesem Grund wird die clientseitige Validierung nur von Internet Explorer 4.0 und höheren Versionen unterstützt, da sie die Objektsprache des DOMs in Internet Explorer nutzt.

Verglichen mit der serverseitigen Validierung geben die Steuerelemente bei der clientseitigen Validierung lediglich andere Elemente in HTML aus. Davon abgesehen sind die Ereignissequenzen absolut identisch. Die serverseitige Validierung wird weiterhin ausgeführt. Dies mag nebensächlich erscheinen, ist jedoch aufgrund folgender Tatsache von Bedeutung:

  • Unter Umständen werden Clientskripts von einigen Validierungssteuerelementen nicht unterstützt. Ein gutes Beispiel hierfür ist die Verwendung eines CustomValidator-Steuerelements in einer Servervalidierungsfunktion, jedoch nicht in einer Clientvalidierungsfunktion.

  • Sicherheitsaspekte: Eine Seite mit Skript kann sehr leicht deaktiviert oder geändert werden. Zwar können Sie mit Skripts Ihren Benutzern sofortiges Feedback bieten, dennoch sollten Sie keine Skripts zur Vermeidung einer fehlerhaften Eingabe von Daten in Ihr System verwenden. Aus diesem Grund sollten Sie ein CustomValidator-Steuerelement für Clientvalidierungsfunktionen nie ohne entsprechende Servervalidierungsfunktion verwenden.

Jedes Validierungssteuerelement stellt sicher, dass ein Clientskript-Standardblock in die Seite ausgegeben wird. Dabei handelt es sich nur um eine geringe Menge Skript, einschließlich einem Verweis auf Code in einer Skriptbibliothek namens WebUIValidation.js. Diese Datei, die separat gedownloadet und vom Browser zwischengespeichert werden kann, enthält sämtliche logischen Informationen für die clientseitige Validierung.

Informationen zur Skriptbibliothek

Da über das Validierungsweb Skript in einer Skriptbibliothek gesteuert wird, muss nicht der gesamte Code zur clientseitigen Validierung direkt in die Seite ausgegeben werden. Der Hauptskript-Dateiverweis sieht wie folgt aus:

<script language="javascript"       
src="/_aspx/1.0.9999/script/WebUIValidation.js"></script> 

Standardmäßig wird die Skriptdatei im Standardstamm des Verzeichnisses _aspx installiert. Der Verweis auf diese Datei erfolgt mit einer zum Stamm relativen Includedirektive im Skript, die mit einem Schrägstrich (/) beginnt. Dieser Verweis bedeutet, dass nicht jedes einzelne Projekt die Skriptbibliothek enthalten muss und dass sämtliche Seiten auf einem Computer auf dieselbe Datei verweisen können. Außerdem enthält der Verweispfad die Versionsnummer der Common Language Runtime, sodass auf einem Computer verschiedene Runtimeversionen laufen können.

Diese Datei finden Sie im standardmäßigen virtuellen Stammverzeichnis. Ihr Speicherort wird in der Datei config.web angegeben, einer XML-Datei für die meisten ASP+-Einstellungen. Nachstehend sehen Sie die Definition des Speicherortes in dieser Datei:

    <webcontrols 
        clientscriptslocation="/_aspx/{0}/script/" 
    />         

Lesen Sie das Skript, um den Vorgang besser verstehen zu können. Von einer Änderung der Skripts sollten Sie jedoch absehen, da ihre Funktion eng an eine bestimmte Runtimeversion gebunden ist. Wenn die Runtime aktualisiert wird, müssen u.U. auch die Skripts entsprechend aktualisiert werden. Dabei verlieren Sie entweder die von Ihnen vorgenommenen Änderungen, oder die Skripts funktionieren nicht mehr. Verwenden Sie zum Ändern von Skripts für ein bestimmtes Projekt eine Kopie der Dateien, und lassen Sie Ihr Projekt darauf verweisen, indem Sie den Speicherort der Dateien mit einer eigenen config.web-Datei überschreiben. Enthält die Zeichenfolge die Formatdirektive "{0}", wird diese durch die Runtimeversionsnummer ersetzt. Sie können diesen Speicherort problemlos in einen relativen oder absoluten Verweis ändern.

Deaktivieren der clientseitigen Validierung

In einigen Fällen sollte keine clientseitige Validierung ausgeführt werden, z.B. wenn eine Seite nur wenige Eingabefelder aufweist. Für eventuell vorhandene logische Daten muss ohnehin immer ein Roundtrip zum Server durchgeführt werden. Eine dynamische Anzeige von Fehlermeldungen auf dem Client hat möglicherweise nachteilige Auswirkungen auf Ihr Layout.

Sie deaktivieren die clientseitige Validierung mit Hilfe der Page-Direktive

clienttarget=downlevel

. Sie steht am Anfang der ASPX-Datei und sieht wie folgt aus:

<%@ Page Language="c#" clienttarget=downlevel %>

Der Standardwert dieser Direktive lautet "auto", d.h., die clientseitige Validierung wird nur für Microsoft Internet Explorer 4.0 oder höher ausgeführt.

Anmerkung: In Beta 1 deaktiviert diese Direktive leider nicht nur die Validierung, sondern veranlasst das Rendern aller Websteuerelemente unter Verwendung von HTML 3.2-Tags, was zu unbeabsichtigten Ergebnissen führen kann. Die endgültige Version wird dieses Problem besser steuern können.

Die clientseitige Sequenz

Nachstehend sehen Sie die Sequenz von Ereignissen beim Ausführen einer Seite mit clientseitiger Validierung:

  1. Während die Seite in den Browser geladen wird, wird auf jedem Validierungssteuerelement eine kurze Initialisierung ausgeführt. Die Steuerelemente werden als <span>-Tags mit HTML-Attributen ausgegeben, die ihren Eigenschaften auf dem Server entsprechen. Wichtig bei diesem Vorgang ist, dass alle Eingabeelemente, auf die die Validatoren verweisen, "angeschlossen" werden. Diese Eingabeelemente lassen ihre Clientereignisse ändern, sodass die Validierungsroutinen bei jeder Eingabeänderung aufgerufen werden.

  2. Der Code in der Skriptbibliothek wird ausgeführt, während die Benutzer auf der Seite von einem Feld zum nächsten wechseln. Wenn ein abhängiges Feld geändert wird, werden die Validierungsbedingungen neu bewertet und der Validator wird entsprechend ein- oder ausgeblendet.

  3. Wenn der Benutzer das Formular absenden möchte, werden sämtliche Validatoren neu bewertet. Sind sie gültig, wird das Formular an den Server gesendet. Falls einer oder mehrere Fehler auftreten, finden verschiedene Vorgänge statt:

    • Der Sendevorgang wird abgebrochen, und das Formular wird nicht auf den Server zurückgeschrieben.

    • Jeder ungültige Validator wird angezeigt.

    • Wenn die Validierungszusammenfassung den Wert ShowSummary=true ergibt, sammelt sie sämtliche Fehler aus den Validierungssteuerelementen und aktualisiert ihren Inhalt anhand dieser Daten.

    • Die Validierungszusammenfassung zeigt den Wert ShowMessageBox=true an, sammelt die Fehler und blendet sie auf dem Client als Meldung ein.

Da die clientseitigen Validierungssteuerelemente bei jeder Eingabeänderung und jedem Senden von Formularen ausgeführt werden, werden sie i.d.R. mindestens zweimal auf dem Client ausgewertet. Beachten Sie, dass sie nach dem Sendevorgang auch noch auf dem Server neu bewertet werden.

Die Client-API

Der Client besitzt eine Mini-API, mit der Sie verschiedene Effekte mit Ihrem eigenen clientseitigen Code erreichen können. Da bestimmte Routinen nicht ausgeblendet oder verborgen werden können, können Sie theoretisch sämtliche Variablen, Attribute und Funktionen verwenden, die vom clientseitigen Skript definiert wurden. Bei vielen dieser Objekte handelt es sich jedoch um Implementierungsdetails, die geändert werden können. In der folgenden Tabelle sind die clientseitigen Objekte zusammengefasst, die Sie vorrangig verwenden sollten.

Tabelle 3: Clientseitige Objekte

Name

Typ

Beschreibung

Page_IsValid

Boolesche Variable

Zeigt an, ob die Seite derzeit gültig ist. Die Validierungsskripts veranlassen die ständige Aktualisierung dieser Anzeige.

Page_Validators

Elementarray

Ein Array, das sämtliche Validatoren der Seite enthält.

Page_ValidationActive

Boolesche Variable

Zeigt an, ob die Validierung ausgeführt werden soll. Setzen Sie diese Variable auf False, um die Validierung automatisch zu deaktivieren.

isvalid

Boolesche Eigenschaft

Diese Eigenschaft in jedem Clientvalidator zeigt an, ob er derzeit gültig ist. In der PCD-Version wurde sie mit Klein- und Großbuchstaben (IsValid) angegeben.

Umgehen der Validierung auf dem Client

Oftmals benötigen Sie eine Abbrechen- oder Navigationsschaltfläche auf einer Seite. In diesem Fall soll auch eine fehlerhafte Seite über die Schaltfläche gesendet werden. Da das onclick-Ereignis der clientseitigen Schaltfläche vor dem onsubmit-Ereignis der Seite auftritt, können Überprüfungen des Sendevorgangs vermieden und die Validierung umgangen werden. Nachstehend sehen Sie den erforderlichen Code, wenn Sie für den Vorgang ein HTML-Image-Steuerelement als Abbrechen-Schaltfläche verwenden:

<input type=image runat=server  
   value="Abbrechen"  
   onclick="Page_ValidationActive=false;"   
   OnServerClick=cmdCancel_Click > 

Die Verwendung eines Button- oder ImageButton-Steuerelements ist etwas schwer verständlich, da vom onclick-Ereignis als dem gleichnamigen serverseitigen Ereignis ausgegangen wird. Stattdessen müssen Sie das Ereignis im Clientskript festlegen:

<asp:ImageButton runat=server id=cmdImgCancel 
AlternateText="Abbrechen"  
OnClick=cmdCancel_Click/> 
<script language="javascript">  
document.all["cmdImgCancel "].onclick =  
           new Function("Page_ValidationActive=false;"); 
</script> 

Alternativ dazu können Sie die Abbrechen-Schaltfläche auch so programmieren, dass sie zurückschreibt, ohne ein submit-Ereignis im Clientskript zu verursachen. Ein Beispiel hierfür sind die Steuerelemente HtmlInputButton und LinkButton.

Spezialeffekte

Eine weitere übliche Anforderung sind über die von den Validatoren selbst angezeigten Fehlermeldungen hinausgehende Effekte. In diesem Fall müssen Sie Änderungen des Verhaltens auf dem Server und dem Client vornehmen. Angenommen, die Farbe einer Beschriftung soll sich abhängig von der Gültigkeit der Eingabe ändern. Der entsprechende Code für den Server sieht dann so aus:

public class ChangeColorPage : Page { 
    public Label lblZip; 
    public RegularExpressionValidator valZip; 
    protected override void OnLoad(EventArgs e) {             
        lblZip.ForeColor = valZip.IsValid? Color.Black : Color.Red; 
    }                
} 

Wenn Sie nun jedoch die Validierung nach diesem Muster ändern und keine entsprechende Operation auf dem Client vornehmen, ist sie inkonsistent. Validierungsframeworks ersparen Ihnen eine Menge doppelter Arbeit, aber zusätzliche Effekte müssen an zwei Stellen programmiert werden. Nachstehend finden Sie ein Clientfragment, das denselben Vorgang ausführt:

<asp:Label id=lblZip runat=server  
   Text="Zip Code:"/>  
<asp:TextBox id=txtZip runat=server  
   OnChange="txtZipOnChange();" /></asp:TextBox><br> 
<asp:RegularExpressionValidator id=valZip runat=server 
   ControlToValidate=txtZip 
   ErrorMessage="Ungültige Postleitzahl"  
   ValidationExpression="[0-9]{5}" /><br> 
<script language=javascript> 
function txtZipOnChange() { 
   // Nichts ausführen, wenn die Validierung nicht auf dem Client ausgeführt wird 
   if (typeof(Page_Validators) == "undefined")  return; 
   // Farbe der Beschriftung ändern 
   lblZip.style.color = valZip.isvalid ? "Black" : "Red"; 
} 
</script> 

Client-APIs in Beta 1

In der Beta 1-Version stehen mit Hilfe einiger Funktionen, die vom clientseitigen Skript aufgerufen werden können, einige zusätzliche Szenarios zur Verfügung.

Tabelle 4: Vom Clientskript aufgerufene Funktionen

Name

Beschreibung

ValidatorValidate(val)

Verwendet einen Clientvalidator als Eingabe und veranlasst den Validator, seine Eingabe zu prüfen und die Anzeige zu aktualisieren.

ValidatorEnable(val, enable)

Verwendet einen Clientvalidator und einen booleschen Wert. Aktiviert/deaktiviert einen Clientvalidator. Ein deaktivierter Validator kann keine Bewertungen ausführen und erscheint immer als gültig.

ValidatorHookupControl(control, val)

Verwendet ein Eingabe-HTML-Element und einen Clientvalidator. Ändert oder erstellt das Änderungsereignis des Elements, sodass der Validator bei Änderungen aktualisiert wird. Dies ist nützlich für benutzerdefinierte Validatoren, die von mehreren Eingabewerten abhängen.

Besonders nützlich ist die Möglichkeit zum Aktivieren bzw. Deaktivieren von Validatoren. Wenn die Validierung nur in einigen Szenarios aktiviert werden soll, müssen Sie u.U. die Aktivierung auf Server und Client ändern, um dem Benutzer das Senden der Seite zu ermöglichen.

Es folgt das vorherige Beispiel mit einem Feld, das nur überprüft wird, wenn ein Kontrollkästchen deaktiviert wird:

    public class Conditional : Page { 
        public HtmlInputCheckBox chkSameAs; 
        public RequiredFieldValidator rfvalShipAddress; 
        protected override void Validate() { 
            bool enableShip = !chkSameAs.Checked; 
            rfvalShipAddress.Enabled = enableShip; 
            base.Validate(); 
        } 
    } 

Die Entsprechung für den Client sieht folgendermaßen aus:

<input type=checkbox runat=server id=chkSameAs  
   onclick="OnChangeSameAs();" >Identisch mit Rechnungsadresse<br> 
<script language=javascript> 
function OnChangeSameAs() { 
    var enableShip = !event.srcElement.status; 
    ValidatorEnable(rfvalShipAddress, enableShip); 
} 
</script> 

 

Gültigkeitsregeln und verständliche Fehlermeldungen

Jeder Validator zeigt eine bestimmte Fehlermeldung zu einer bestimmten Bedingung in einem bestimmten Steuerelement an. Die Regeln, nach denen die Gültigkeit bestimmt wird, mögen Ihnen als Entwickler zunächst verwirrend erscheinen. Sie sind jedoch notwendig, um Ihnen die Erstellung von Fehlermeldungen zu gestatten, die wirklich hilfreich für den Benutzer sind.

Alle Validatoren (mit Ausnahme von RequiredFieldValidator) werden als gültig bewertet, wenn sie leer sind. Ist ein leerer Wert nicht gültig, müssen Sie i.d.R. einen RequiredFieldValidator zusätzlich zu einem anderen Validator bereitstellen. Dies ist unabdingbar, da nahezu immer unterschiedliche Fehlermeldungen für leere und gültige Validatoren angezeigt werden sollen. Anderenfalls erhalten Sie solch verwirrende Meldungen wie "Geben Sie einen Wert ein. Der Wert muss zwischen 1 und 10 liegen."

Für die Validatoren CompareValidator und RangeValidator gilt eine weitere besondere Regel, wenn die Eingabefelder nicht in den angegebenen Datentyp konvertiert werden können. Die Bewertung der Gültigkeit für den CompareValidator mit festgelegtem ControlToCompare-Validator geschieht wie folgt:

  1. Wenn das Eingabefeld, auf das ControlToValidate verweist, leer ist, ist es gültig.

  2. Wenn das Eingabefeld, auf das ControlToValidate verweist, nicht in den angegebenen Datentyp konvertiert werden kann, ist es ungültig.

  3. Wenn das Eingabefeld, auf das ControlToCompare verweist, nicht in den angegebenen Datentyp konvertiert werden kann, ist es gültig.

  4. Die Eingabefelder werden in den angegebenen Datentyp konvertiert und verglichen.

Der dritte Schritt mag unlogisch erscheinen, ist aber erforderlich, da es sonst schwierig wäre, eine logische Fehlermeldung für den Validator zu schreiben, wenn dieser die Gültigkeit von mehreren Feldern gleichzeitig prüfen würde. Verwenden Sie für Berichte über Fehlerbedingungen im ControlToCompare-Eingabefeld einen einzelnen Validator. Ähnlich funktioniert der RangeValidator mit seinen Angaben zu den minimalen und maximalen Eigenschaften.

 

Auswirkungen der Eigenschaften "Enabled", "Visible" und "Display"

Der Unterschied zwischen den Eigenschaften Enabled, Visible und Display für Validatoren mag auf den ersten Blick nicht erkennbar sein.

Mit Display=None können Sie einen Validator festlegen, der zwar nichts direkt anzeigt, dennoch aber weiterhin bewertet wird, sich weiterhin auf die Gesamtgültigkeit auswirkt und weiterhin der Zusammenfassung auf Server- und Clientseite einen Fehler hinzufügen kann. Bei der clientseitigen Validierung bestimmen diese Werte, ob die Sichtbarkeit oder die Anzeigestilattribute zur Aktivierung/Deaktivierung des Validators verwendet werden sollen. Für die serverseitige Validierung bedeutet Display=Dynamic, dass bei einer gültigen Eingabe nichts angezeigt wird. Bei Display=Static hingegen wird ein einzelnes geschütztes Leerzeichen ("&nbsp") ausgegeben. Dieses zuletzt genannte Verhalten dient dazu, dass Tabellenzellen, die lediglich Validatoren enthalten, bei Gültigkeit nicht gänzlich verloren gehen.

Warum verwenden wir nicht einfach Visible=false, um einen Validator auszublenden? In ASP+ kommt der Visible-Eigenschaft eines Steuerelements eine wichtige Bedeutung zu: ein Steuerelement mit dem Wert Visible=false wird für Vorrendering- oder Renderingvorgänge grundsätzlich nicht verarbeitet. Ein Validator mit dem Wert Visible=false zeigt daher nicht nur nichts an, sondern funktioniert auch nicht. Er wird nicht bewertet, hat keine Auswirkungen auf die Gültigkeit einer Seite und fügt der Zusammenfassung keine Fehler hinzu.

Die Enabled-Eigenschaft ist eine Art Mittellösung. Enabled=false hat in den meisten Fällen dieselbe Auswirkung wie Visible=false. Bei Verwendung mit Beta 1 und höheren Versionen gibt es einen wichtigen Unterschied: Bei der clientseitigen Validierung wird ein deaktivierter Validator weiterhin an den Browser gesendet, allerdings im deaktivierten Zustand. Mit der ValidatorEnable-Funktion im Clientskript können Sie ihn aktivieren.

Beachten Sie bei der Steuerung der Validierung mit Hilfe der Visible- oder Enabled-Eigenschaft die oben genannte Sequenz von Ereignissen auf dem Server, und ändern Sie sie vor der Validierung bzw. bewerten Sie sie nach der Validierung erneut. Anderenfalls spiegeln ihre IsValid-Werte u.U. nicht die Änderungen an den Eigenschaften wider.

 

Das "CustomValidator"-Steuerelement

Der Validierungsframework lässt sich am einfachsten mit dem CustomValidator-Steuerelement erweitern. Mit seiner Hilfe führen Sie entweder eine Validierung aus, die nicht von einem anderen Validierungssteuerelement ausgeführt wird, oder Sie führen eine Validierung aus, für die ein Zugriff auf Informationen auf dem Server, z.B. auf eine Datenbank oder einen Webdienst, erforderlich ist.

Wenn Sie ein CustomValidator-Steuerelement mit lediglich einer definierten Servervalidierungsfunktion hinzufügen, nimmt es nicht an der clientseitigen Validierung teil. Während der Benutzer die Eingabefelder auf einer Seite durchläuft, wird es nicht aktualisiert und erfordert vor der Validierung einen Roundtrip zum Server. Wenn Sie mit dem CustomValidator-Steuerelement eine Überprüfung ausführen, für die keine Serverinformationen benötigt werden, können Sie den Validator auch unter Verwendung der ClientValidationFunction-Eigenschaft vollständig an der clientseitigen Validierung teilnehmen lassen. Wenn Sie mit einer ClientValidationFunction-Eigenschaft arbeiten, sollte diese im Idealfall dieselben Überprüfungen wie der Servervalidierungshandler ausführen. Ist dies nicht der Fall, sollte es eine Untermenge dieser Überprüfung ausführen. Vermeiden Sie den Einsatz von Clientvalidierungsfunktionen, die mehr Überprüfungen ausführen als auf dem Server stattfinden, da sie von Hackern leicht umgangen werden können.

Nachstehend sehen Sie ein einfaches Beispiel eines CustomValidator-Steuerelements, das auf dem Client und dem Server ausgeführt wird und die Eingabe auf eine gerade Zahl überprüft. Zunächst die Serverfunktion (in C#):

        public bool ServerValidation(object source, string value) { 
            try {  
                int i = int.FromString(value); 
                return ((i % 2) == 0); 
            } catch { 
                return false; 
            } 
        } 

Als Nächstes sehen Sie, wie dieses Steuerelement zusammen mit einer Clientvalidierungsfunktion, die dieselbe Überprüfung ausführt, auf dem Client arbeitet. In der Regel ist der Code in JScript geschrieben, Sie können jedoch auch in VBScript schreiben, wenn Sie die Objektsprache von Microsoft Internet Explorer verwenden.

<asp:CustomValidator id="customVal2" runat=server  
    ErrorMessage="Zahl ist nicht durch 2 teilbar!"    
    ControlToValidate="txtCustomData"  
    OnServerValidationFunction=ServerValidation  
    ClientValidationFunction="CheckEven" /><br> 
Datenfeld: <asp:TextBox id="txtCustomData" runat="server" /> 
<script language=javascript> 
<!-- 
function CheckEven(source, value) { 
    var val = parseInt(value, 10); 
    if (isNaN(val)) 
        return false; 
    return ((val % 2) == 0); 
} 
// --> 
</script> 

Beachten Sie bei der Verwendung des CustomValidator-Steuerelements Folgendes:

  • Wie alle anderen Validierungssteuerelemente auch (mit Ausnahme von RequiredFieldValidator) gilt es als gültig, wenn das Eingabefeld leer ist.

  • Bei älteren Browsern oder deaktivierter Clientvalidierung wird die Clientvalidierungsfunktion nicht aufgerufen. Sie brauchen den Browser vor dem Definieren der Funktion zwar nicht selbst zu überprüfen, müssen jedoch sicherstellen, dass die Funktion allein aufgrund ihrer Definition keine Skriptfehler verursacht. Fügen Sie Ihren Clientcode, wie im Beispiel gezeigt, immer als HTML-Kommentar hinzu.

  • Ihrer Clientfunktion werden entsprechend den Parametern, die der Serverfunktion übergeben werden, ebenfalls zwei Parameter übergeben. Bei dem ersten handelt es sich um das Clientvalidatorelement, der zweite ist der Wert, der durch das ControlToValidate-Steuerelement festgelegt wird. Sie haben allerdings auf dem Client auch die Möglichkeit, keine Parameter für Ihre Funktion zu definieren, was keinerlei negative Auswirkungen zeigt.

  • In Beta 1 oder höher können Sie das ControlToValidate-Steuerelement leer lassen. In diesem Modus wird die Serverfunktion einmal pro Roundtrip ausgelöst, die Clientfunktion wird immer einmal pro Sendeversuch ausgelöst. Somit können Sie Steuerelemente validieren, die sich nicht auf andere Art validieren lassen, z.B. ein CheckBoxList-Steuerelement oder eigenständige Optionsschaltflächen. Zudem ist dieser Modus hilfreich, wenn die Bedingung auf mehreren Steuerelementen basiert und nicht bewertet werden soll, während der Benutzer die Eingabefelder auf einer Seite durchläuft.

  • Weiterhin haben Sie in Beta 1 oder späteren Versionen die Möglichkeit, unter Verwendung von Inlineskript, das die Clientfunktion ValidatorHookupControl aufruft (siehe oben), die change-Ereignisse mehrerer Steuerelemente einzubinden.

 

Welche Steuerelemente lassen sich überprüfen?

Wenn ein Validierungssteuerelement auf ein Steuerelement verweisen soll, muss dieses Steuerelement eine Validierungseigenschaft besitzen. Sämtliche Steuerelemente, die validiert werden können, verfügen über ein Attribut mit der Bezeichnung ValidationPropertyAttribute, das angibt, welche Eigenschaft zum Zweck der Validierung gelesen werden soll. Selbst geschriebene Steuerelemente können an der Validierung teilnehmen, wenn Sie eines dieser Attribute zur Angabe der zu verwendenden Eigenschaft zur Verfügung stellen.

Damit die Validierung auch auf dem Client ausgeführt wird, muss diese Eigenschaft dem value-Attribut des HTML-Elements entsprechen, das auf dem Client gerendert wird. Viele komplexe Steuerelemente wie beispielsweise DataGrid und Calendar besitzen keinen Wert auf dem Client und können daher nur auf dem Server validiert werden. Aus diesem Grund können nur Steuerelemente an einer Validierung teilnehmen, die den HTML-Elementen entsprechen. Da ein Steuerelement zudem einen einzelnen logischen Wert auf dem Client besitzen muss, kann RadioButtonList beispielsweise validiert werden, CheckBoxList hingegen nicht.

 

Zu guter Letzt

Möglicherweise haben Sie jetzt mehr über die Validierung in ASP+ erfahren als eigentlich geplant. Viel Spaß damit!