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

Artikel: Identifizierung von Controls: Control.ID / .ClientID / .UniqueID

ASP.NET Controls haben 3 verschiedene Eigenschaften, anhand dessen man sie identifizieren kann.
Na gut, man mag denken, desto mehr, desto besser :))

Es kann aber auch genau auch das Gegenteil bedeuten: Verwirrung.

Um die "Bösewichte" mal beim Namen zu nennen:
Serverseitige ID         --> <Control>.ID
Clientseitige ID          --> <Control>.ClientID
Clientseitiger Namen  --> <Control>.UniqueID

Ein kleiner Exkurs zu Classic ASP um mehr über die Hintergründe zu erfahren.
In Classic ASP kann ein erweitertes HelloWorld Script so aussehen:

<form name="myForm" method="post">
    <input type="text" name="txtName" />
    <input type="submit" value="PostBack..." name="btnSubmit" />
</form>
<%
  If Request.Form.Count > 0 Then
      If Request.Form("txtName") <> vbNullString Then
          Response.Write("Hallo " & Request.Form("txtName") & "!")
      End If       
  End If
%>

Wir deklarieren hier alles von Hand und das genau so, wie es schliesslich beim Client ankommt.
Es wird der Name "txtName" für das Html Input Field manuell gesetzt und schliesslich auch für das anschliessende Request.Form benutzt.
Keine Probleme und eine heile Welt also :-)

Nun, was ist den überhaupt in ASP.NET so anders, dass wir hier drei verschiedene Eigenschaften zur Identifizierung eines Controls brauchen, werdet ihr euch wahrscheinlich fragen.
Es ist aber tatsächlich so, dass alle drei Eigenschaften ihre Berechtigung haben, hier also im einzeln:

Serverseitige ID --> <Control>.ID

Die serverseitige ID wird, wie der Name schon sagt, auf dem Server benutzt.

Bei deklerativen oder per Code erstellten Controls / Steuerelementen vergibt man manuell oder per Code automatisiert eine ID.
Diese dient bei der serverseitigen Arbeit zur eindeutigen Identifizierung der Controls.

Beim arbeiten mit ASP.NET benutzt man die meiste Zeit diese ID.
Wichtig zu wissen ist dabei, dass man durch die Schachtelung von Controls oder Schachtelung von Quellcode und Definierung von Namensräumen und Aliase, die jeweiligen IDs auch mehrmals vergeben kann, ohne dass dabei serverseitig die Eindeutigkeit verloren geht.

Schlussendlich wird die ganze Eindeutigkeit eben durch die Möglichkeiten auf dem Server (Schachtelung, Namensräume, Aliase) konsistent gehalten, ohne dass dabei Probleme entstehen.


Clientseitige ID --> <Control>.ClientID

Jetzt kommt die Kehrtwende, wir arbeiten ja nicht ausschliesslich auf dem Server, sondern wollen uns auch die Möglichkeiten auf dem Client nicht entgehen lassen.
Auf dem Client können wir mit Javascript oder VBScript (nur Internet Explorer) weiterarbeiten, ohne auf Rücksprache mit dem Server angewiesen zu sein.

Um überhaupt mit Javascript arbeiten zu können, müssen wir serverseitig den entsprechenden Code konstruieren und dem Client im Ausgabestrom zur Verfügung stellen.

Jetzt sieht die Situation mit den IDs schon wieder ganz anders aus.
Auf dem Client wird eine Html Seite (und evt. weitere Elemente) empfangen und verarbeitet. Im Gegensatz zum Server, haben wir hier keine Möglichkeiten mehr, von den oben genannten Vorteilen (Schachtelung, Namensräume, Aliase) zu profitieren.

ASP.NET wirkt diesem Problem entgegen, indem es, * bei Bedarf, für den Client aus den auf dem Server eindeutigen Namen / IDs, jeweils eindeutige Namen und IDs für den Client generiert.
So haben wir auf dem Server und auf dem Client jeweils eine eindeutige Namensumgebung ohne Konflikte.

* Wenn ein Control z.B. nur an die Page selber gehängt wird, kommen keine Präfixe in die ClientID bzw. UniqueID bzw. vor die normale ID.

Wollen wir jetzt clientseitig mit Javascript weiterarbeiten, kommt serverseitig zuerst <Control>.ClientID ins Spiel, diese Eigenschaft enthält die ID, die von ASP.NET automatisch generiert und zum Client gesendet wird.
Wir übergeben dem Javascript Code, der dann schlussendlich vom Server zum Client geschickt wird, jeweils die ClientID, die ASP.NET auch in den Html Quellcode rendert.
So können wir per Javascript auf die jeweiligen Controls clientseitig zugreifen.

Die clientseitige ID setzt sich aus dem Container- und dem eigentlichen Namen zusammen.
Beispielsweise ist in einem UserControl "uc1" ein Label "lblTest" enthalten, so lautet die ClientID: uc1_lblTest

Clientseitiger Namen --> <Control>.UniqueID

Am oberen Classic ASP Beispiel sehen wir, dass für die Übermittlung von Formularen mittels POST, das Name-Attribut eines Html Input Fields zur Identifizierung benutzt wird.
Die UniqueID ist im Grunde dasselbe wie die ClientID, nur dass man sich hier auf den Namen bzw. das Name-Attribut des Elementes bezieht und der Name anders codiert wird.

Die Zusammensetzung der ID ist identisch mit dem oberen Beispiel, nur dass zur Trennung der Namen, jeweils ein Dollarzeichen benutzt wird. UniqueID wird z.B. für den Fall benutzt, wenn man per Request.Form[] manuell einen Wert abrufen möchte.
Das Name-Attribut wird auf dem Client also wie folgt lauten: uc1$lblTest

Beispiel und Demonstration von Problemen die auftreten könnten

Ich habe für euch ein Beispiel zusammengestellt, das sowohl die Nutzung von serverseitigen IDs und UniqueID demonstriert, als auch  im gleichen Atemzug auch ein mögliches Problem aufzeigt.

Im Beispiel verwende ich eine normale ASPX Seite mit Codebehind so wie auch ein UserControl das im Prinzip gleich aufgebaut ist, wie die ASPX Seite.
Die ASPX Seite bindet im unteren Bereich das UserControl ein.
Nicht nur der deklerative Teil, sondern auch der codierte, sieht praktisch gleich aus.
Auch die Benennung in Form von serverseitigen IDs ist zu Demonstrationszwecken völlig identisch.

Das Beispiel ist im Grunde gleich aufgebaut, wie das obere Classic ASP Beispiel.
Wir haben ein Formular, eine TextBox und ein Submit Button. Desweiteren sind auch noch ein paar Statuslabels vorhanden.

Man gibt seinen Namen ein und erhält ihn dann inklusive einer Begrüssung angezeigt, im UserControl, sowie auch auf der Seite.
Wenn man das Beispiel ausführt und bei beiden TextBoxen jeweils einen Wert eingibt, fällt gleich auf, dass bei der Ausgabe vom UserControl bei der Abfrage per Request.Form auf die <Control>.ID, den Wert vom Formular der ASPX Seite selber, angezeigt wird.

Der Grund ist einfach, wir haben serverseitig in der ASPX Seite, sowohl auch im UserControl identische Bezeichner, für unserer TextBoxen (und den ganzen Rest), wenn wir jetzt also versuchen clientseitig mithilfe der <Control>.ID auf den Wert zuzugreifen, fallen wir hier in einen Namenskonflikt.

Die Request.Form[] Abfrage per <Control>.ClientID bringt uns auch nicht weiter, da bei der Übertragung per POST auf die Namen zurückgegriffen wird und nicht auf die ID!

Hier ist <Control>.UniqueID also die Qual der Wahl, denn diese Eigenschaft liefert uns das automatisch generierte Name-Attribut des Controls.

Abschliessende Worte

Im Grunde benötigt man bei der Arbeit mit ASP.NET meistens nur ID oder die ClientID.
Request.Form sowie auch Response.Write sollte und benötigt man praktisch nicht mehr.

Das Modell von ASP.NET bietet hier viel komfortablere Möglichkeiten, anstelle von Response.Write() bieten sich Controls / Steuerelemente an, die man dynamisch per Inhalt füllen kann, z.B. <Control>.Text, etc..

Anstelle von Request.Form[] kann man im Code einfach auf die .Text Eigenschaft der TextBoxen zugreifen.
So wird die ganze Arbeit mit der Identifizierung der Controls von ASP.NET gehandelt und vereinfacht.
Siehe auch: Die alten Bekannten - Response.Write() und Request.Form[]

Möglichkeiten um Javascript die ClientID eines Controls bekanntzumachen, finden sich auf folgender Seite:

Beispielprojekt:

MSDN Links:

Dank geht an Kai Gloth für die Idee zum Artikel, sowie den Hinweis zu <Control>.UniqueID im Bezug auf Request.Form[]

Bearbeitung / Korrekturen:
23.05.07 - Hinweis zum generieren bzw. nichtgenerieren der IDs hinzugefügt
28.11.07 - Link zum Codeclip von Daniel Walzenbach hinzugefügt
17.03.08 - Link zu "Die alten Bekannten - Response.Write() und Request.Form[]" hinzugefügt

Veröffentlicht Montag, 9. April 2007 19:46 von Peter Bucher

Kommentare

# Dateipfad ohne Upload der Datei auslesen

Es gibt Leute, die haben Anforderungen, dann gibt es aber auch noch Leute die haben spezielle Anforderungen

Mittwoch, 2. Mai 2007 20:17 by Peter Bucher

# Alles neu oder was?

Info &amp; Statistiken Ja, es gibt Neuigkeiten auf meinem Blog, aber es ist nicht alles neu ;-) Unter

Freitag, 24. August 2007 01:45 by Peter Bucher

# TextBox mit Mode Password - Vorbelegen und Wert erhalten

Das TextBox Control mit der Eigenschaft TextMode="Password" genannt) legt ein anderes Verhalten an den

Mittwoch, 5. September 2007 20:53 by Peter Bucher

# Masterpage dynamisch per Code umschalten

Masterpages sind eine wirklich tolle Neuerung von ASP.NET 2.0. Um so mehr entfaltet sich die Wirkung,

Sonntag, 30. September 2007 23:29 by Peter Bucher

# Masterpage dynamisch per Code umschalten

Masterpages sind eine wirklich tolle Neuerung von ASP.NET 2.0. Um so mehr entfaltet sich die Wirkung,

Samstag, 10. November 2007 02:23 by Peter Bucher

# Masterpage dynamisch per Code umschalten

Masterpages sind eine wirklich tolle Neuerung von ASP.NET 2.0. Um so mehr entfaltet sich die Wirkung,

Montag, 12. November 2007 20:12 by Peter Bucher

# TextBox mit Mode Password - Vorbelegen und Wert erhalten

Das TextBox Control mit der Eigenschaft TextMode="Password" legt ein anderes Verhalten an den Tag, als

Montag, 19. November 2007 14:01 by Peter Bucher

# Ein simples Listen Menü mit ASP.NET

Das mitgelieferte Menü Control von ASP.NET rendert Tabellen und vieles unnötiges Markup. Mit den CSS

Dienstag, 1. April 2008 20:06 by Peter Bucher

# Events für User- und CustomControls definieren und benutzen

In der Welt von ASP.NET gibt es - im Gegensatz zu Classic ASP - ein Eventsystem das in der ASP.NET Engine

Donnerstag, 12. Juni 2008 21:45 by Peter Bucher

# Asynchronen AJAX PostBack erkennen

Um zu erkennen ob der aktuelle Request durch einen ASP.NET AJAX PostBack ausgelöst wurde, muss man nur

Donnerstag, 31. Juli 2008 16:42 by Jürgen Gutsch

# AsyncPostBackTrigger per Code erzeugen

Entgegen der Dokumentation auf http://www.asp.net/ lassen sich PostBackTrigger und AsyncPostBackTrigger

Freitag, 1. August 2008 09:39 by Jürgen Gutsch

# Zwei Ansätze wie mit den ClientIDs von ASP.NET umgegangen werden kann

Wie den meisten schon bekannt sein wird, erzeugt ASP.NET ClientIDs die auf dem Client genutzt werden

Dienstag, 2. September 2008 00:57 by Peter Bucher
Anonyme Kommentare sind nicht zugelassen