Peter Bucher - Mein Experiment, meine Spielereien, meine Welt...   ·   Stefan Falz   ·   Jürgen Gutsch   ·   Golo Roden   ·   ASP.NET Zone   ·   Microsoft ASP.NET
Willkommen bei ASP.NET Zone. Anmelden | Registrieren | Hilfe

CustomValidator - Ein Anwendungsbeispiel

Keine Frage, mit den Validator Controls von ASP.NET wird uns das Leben etwas leichter gemacht.
Jedoch lässt sich nicht jeder Fall auf diese out-of-the-box Lösungen abbilden.

Neben den üblichen Validator Controls gibt es noch ein spezielles Controls: Den CustomValidator.

Mit dem CustomValidator Control ist es uns - wie der Name schon sagt - möglich, spezielle Validierungen abzubilden.
Dies sowohl auf der Client- als auch auf der Serverseite.
Folgend ein Beispiel für die Anwendung des CustomValidators.

Aufgabe
Es ist eine ListBox vorhanden, zu der Einträge hinzugefügt und gelöscht werden können.
Die Seite soll valid sein, wenn mindestens ein Eintrag in der ListBox vorhanden ist.

ASPX:
<asp:DropDownList ID="ddlAuswahl" runat="server">
    <asp:ListItem Text="Schweiz" />
    <asp:ListItem Text="Deutschland" />
    <asp:ListItem Text="Amerika" />
</asp:DropDownList>
<asp:Button ID="btnZuweisen" Text="Auswahl zuweisen" CausesValidation="false" runat="server" />
<br />
<asp:ListBox ID="lbxTest" Width="100" runat="server" />
<asp:Button ID="btnEntfernen" Text="Auswahl entfernen" CausesValidation="false" runat="server" />
<asp:CustomValidator
    ID="valTest"
    ControlToValidate="lbxTest"
    ClientValidationFunction="valTest_ClientValidate"
    ValidateEmptyText="true"
    ErrorMessage="Mindestens eine Option hinzufügen"
    runat="server" />
<br />
<asp:Button ID="btnSubmit" Text="PostBack..." runat="server" />

Es besteht eine DropDownList mit einer Auswahl an Ländern, diese können selektiert und mit Klick auf den Zuweisen Button zur ListBox hinzugefügt werden.
Wichtig sind hier die Eigenschaften des Validtors, im einzelnen:

ControlToValidate:
Wie der Name schon sagt, muss hier die ID des zu validierenden Controls angeben werden.

ClientValidationFunction:
Dieser Eigenschaft fügen wir den Namen einer clienseitigen Javascript Funktion zu, die wir weiter unten sehen.

ValidateEmptyText:
Wenn diese Eigenschaft nicht auf true steht, brauchts zusätzlich einen anderen Validator (bspw. RequiredFieldValidator),
und der CustomValidator feuert nur, wenn ein Wert vorhanden ist.
Somit müssen wir diese Eigenschaft auf false stellen, um alle Fälle mit dem CustomValidator abzufangen.
Siehe: CustomValidator - Weshalb bei leeren Werten nicht validiert wird

Zu beachten ist jeweils noch die Eigenschaft CausesValidation der zwei Buttons (Zuweisen und Löschen).
Damit sagen wir ASP.NET, das beim Klicken auf diese Buttons keine Valdation ausgeführt werden soll.
Wenn wir das nicht tun würden, könnte das Formular nie valid sein, da es nie abgesendet wird (Bei clientseitiger Validation).

C#:
protected void Page_Load(object sender, EventArgs e) {
    // Event Handler anmelden
    this.valTest.ServerValidate += new ServerValidateEventHandler(valTest_ServerValidate);
    this.btnZuweisen.Click += new EventHandler(btnZuweisen_Click);
    this.btnEntfernen.Click += new EventHandler(btnEntfernen_Click);
}


void btnZuweisen_Click(object sender, EventArgs e) {
    // Item hinzufügen, falls noch nicht vorhanden
    if(this.lbxTest.Items.FindByText(this.ddlAuswahl.SelectedItem.Text) == null)
        this.lbxTest.Items.Add(new ListItem(this.ddlAuswahl.SelectedItem.Text));
}

void btnEntfernen_Click(object sender, EventArgs e) {
    // Item entfernen
    this.lbxTest.Items.Remove(this.lbxTest.SelectedItem);
}

void valTest_ServerValidate(object source, ServerValidateEventArgs args) {
    // Serverseitige Validation
    CustomValidator val = source as CustomValidator;
    ListBox lbx         = this.FindControl(val.ControlToValidate) as ListBox;

    args.IsValid = lbx.Items.Count > 0;
}

Im C# Code ist die Logik hinterlegt.
Zuerst werden die benötigten Event Handler für die zwei Buttons und den Validator angemeldet und im Code als Methode hinterlegt.
Beim Zuweisen wird zuerst geschaut, ob dieser Wert schon vorhanden ist. Wenn ja, wird der Wert nicht noch einmal hinzugefügt.
Beim Entfernen wird das selektierte Item entfernt.

In der ServerValidate Methode wird über den Sender (Das Validator Objekt), Page.FindControl() und zwei Castings auf das Control das validiert werden soll, zugegriffen.
Die Prüfung an sich ist sehr trivial. Es wird einfach geschaut, ob die Items Collection mindestens ein Item enthält.
Das wars dann auch schon mit der serverseitigen Validierung.

Jetzt fehlt noch die clientseitige Routine. Also werfen wir doch einmal einen Blick darauf:

Javascript:

<script type="text/javascript">
    function valTest_ClientValidate(sender, args) {
        var controlToValidate = document.getElementById(sender.controltovalidate);
        args.IsValid = controlToValidate.getElementsByTagName('option').length > 0;
    }
</script>

In der clientseitigen Funktion wird die serverseitige Validationslogik per Javascript nachgebildet.
Sie sieht zwar nicht identich aus, jedoch sehr ähnlich.
Über das Argument sender erhalten wir Zugriff auf das clientseitige Validator Objekt.
Dieses hat eine Eigenschaft controltovalidate (Wie das serverseitige Äquivalent), die den Namen des zu validierenden Controls zurückliefert.
Über diese ID und document.getElementById() können wir auf das Control zugreifen, das wir validieren möchten.

Über das clientseitige Objekt der ListBox (clientseitig: Select), kann per <Objekt>.getElementsByTagName('option') auf einen Array
aller Option Felder innerhalb des Select-Tags (clientseitige Abbildung der ListBox) zugegriffen werden.
Schlussendlich ermitteln wir die Länge des Arrays und prüfen ob es mindestens ein Element besitzt.
Das Argument args hat unter anderem eine Eigenschaft IsValid (Wie auch das serverseitige Argument), über das wir das Validationsergebnis mitteilen können.

Hintergrund:
ASP.NET erstellt im Hintergrund automatisch den Javascript Code, sodass ein clientseitiges Objektmodell für die Validierung zur Verfügung steht.
Wer sich mehr dafür interessiert, kann sich den generierten Javascript Code über den Quelltext im Browser ansehen.

Beispielprojekt zum Download:

Veröffentlicht Montag, 11. Februar 2008 22:09 von Peter Bucher

Kommentare

# re: CustomValidator - Ein Anwendungsbeispiel

Die Einstellung der Eigenschaft 'CausesValidation' für die beiden anderen Buttons kann man sich ersparen, wenn man der Listbox und dem Submit-Button eine gemeinsame Validierungsgruppe zuweist. Das macht vor allem Sinn, wenn man auf der Seite noch mehr Form-Controls einsetzt, die andere Zwecke erfüllen und auch nicht der Validierung im Wege stehe sollen.

Donnerstag, 14. Februar 2008 12:09 by kristof

# re: CustomValidator - Ein Anwendungsbeispiel

Hallo Kristof

Stimmt, danke für deinen Hinweis!

Freitag, 15. Februar 2008 00:41 by Peter Bucher
Anonyme Kommentare sind nicht zugelassen