Kapitel 5 Die Page-Klasse
Die Page-Klasse bildet den Hintergrund, auf dem die gesamte ASP.NET-Programmierung stattfindet. Jede Seite ist ein Page-Objekt.
Am Ende des Crashkurses aus dem vorangegangenen Kapitel haben Sie ein kleines Skript erstellt, das einen Namen entgegennimmt und den Anwender anschließend mit seinem Namen begrüßt. Wenn der Anwender jedoch OK anklickt, ohne einen Namen einzugeben, erscheint eine Fehlermeldung. Hier noch einmal der komplette Code:
<!-- name02.aspx -->
<%@ Page Language="VB" Debug="True" Strict="True" %>
<script runat="server">
Sub Page_Load (ByVal Sender As Object, _
ByVal E As EventArgs)
If IsPostBack Then
Page.Validate
If IsValid Then
meldung.Text = "Hallo, " & txtName.Value
End If
End If
End Sub
</script>
<html><head><title>Begrüßung</title></head>
<body><h1>Begrüßung</h1>
<form runat="server">
Wie heißen Sie?
<br><br>
<input runat="server" id="txtName" type="text" >
<asp:RequiredFieldValidator
id="reqTxtName"
ControlToValidate="txtName"
Display="dynamic"
runat="server">
Bitte geben Sie hier Ihren Namen ein.
</asp:RequiredFieldValidator>
<br><br>
<input runat="server" type="submit" value=" OK " >
<br><br>
<asp:Label id="meldung" runat="server" />
</form></body></html>
Vielleicht geht es Ihnen damit so wie mir am Anfang meiner Beschäftigung mit ASP.NET. Es wird zwar intuitiv einigermaßen klar, was hier abläuft, aber im Detail bleibt es ein einziges Rätsel. Die Funktionsweise dieser Seite soll deshalb genauer nachvollzogen werden.
Dabei lernen Sie den zentralen Grundbaustein von ASP.NET näher kennen: Die Page-Klasse. Die Page-Klasse nimmt innerhalb von ASP.NET eine Schlüsselfunktion ein. Für den Webserver ist jede aspx-Seite eine Instanz der Klasse System.Web.UI.Page. Von der Page-Klasse ausgehend können Sie auf jedes Objekt zugreifen, das ASP.NET zu bieten hat.
Weil das Page-Objekt so zentral und vielseitig ist, können viele Merkmale dieser Klasse in diesem Kapitel nur kurz erwähnt werden. Genauer erläutert werden sie in den folgenden Kapiteln. Zugespitzt ließe sich sagen: Um die ASP.NET-Programmierung zu erlernen, reicht es aus, lediglich die Page-Klasse gründlich kennen zu lernen. Diese Klasse bietet so viele Ansatzpunkte für alle Aspekte der Webprogrammierung, dass alle Kapitel dieses Buches in irgendeiner Weise mit der Page-Klasse zu tun haben.
Die Eigenschaft Cache der Page-Klasse bietet beispielsweise Zugriff auf das Cache-Objekt, über das jede Applikation verfügt. Das ist das Thema von Kapitel 15, Leistungssteigerung durch Caching. Die Eigenschaft Session bietet Zugriff auf das HttpSessionState-Objekt, das der aktuellen Sitzung zugeordnet ist. Näheres dazu erfahren Sie in Kapitel 11, Der Status von Seiten, Sitzungen und Applikationen. Daten, die die ganze Webanwendung betreffen, werden in einem Objekt der Klasse HttpApplicationState gespeichert. Dieses Objekt erreichen Sie über die Application-Eigenschaft der Page-Klasse. Details dazu werden in den Kapiteln 11 und 15 erläutert. Und so geht es weiter mit jedem Thema dieses Buches und mit allem, was ASP.NET zu bieten hat.
Tabelle 5.1 listet die Eigenschaften und einige Methoden der Page-Klasse auf.
| Eigenschaften
|
| Application
|
HttpApplicationState
|
Das Application-Objekt
|
| Cache
|
Cache
|
Das aktuelle Cache-Objekt
|
| ClientTarget
|
String
|
Deaktiviert die automatische Erkennung von Browserfunktionen
|
| Controls
|
ControlCollection
|
Auflistung der Control-Objekte, aus denen diese Seite besteht
|
| EnableViewState
|
Boolean
|
Bei True (Standard) behält die Seite ihren Anzeigestatus und den Status der enthaltenen Steuerelemente
|
| ErrorPage
|
String
|
Fehlerseite, zu der umgeleitet wird, wenn eine unbehandelte Ausnahme auf der Seite auftritt
|
| ID
|
String
|
Eindeutiger Bezeichner
|
| IsPostBack
|
Boolean
|
True, wenn die Seite als Antwort auf ein Postback geladen wird
|
| IsValid
|
Boolean
|
True, wenn die Überprüfung der Seite durch die Validierungssteuerelemente erfolgreich war
|
| Page
|
Page
|
Die Page-Instanz selbst
|
| Request
|
HttpRequest
|
Das Request-Objekt der aktuellen Anforderung
|
| Response
|
HttpResponse
|
Das aktuelle Response-Objekt
|
| Server
|
HttpServerUtility
|
Das aktuelle Server-Objekt. Bietet beispielsweise Zugriff auf die HtmlEncode- und MapPath-Methode
|
| Session
|
HttpSessionState
|
Die aktuelle Sitzung
|
| SmartNavigation
|
Boolean
|
True, wenn die intelligente Navigation aktiviert ist. Wird meist über die Page-Direktive gesetzt
|
| TemplateSourceDirectory
|
String
|
Das virtuelle Verzeichnis dieser Seite
|
| Trace
|
TraceContext
|
Das aktuelle TraceContext-Objekt
|
| User
|
User
|
Bietet Informationen zum Benutzer
|
| Validators
|
ValidatorCollection
|
Auflistung aller Validierungssteuerelemente
|
| Visible
|
Boolean
|
True, wenn die Seite dargestellt werden soll
|
| Methoden (Auswahl)
|
| DataBind
|
Führt die Datenbindungen für alle datengebundene Steuerelemente dieser Seite aus.
|
| MapPath
|
Ruft den physischen Pfad ab, auf den ein absoluter bzw. relativer virtueller Pfad verweist.
|
| ResolveUrl (von Control geerbt)
|
Löst einen relativen URL in einen absoluten URL auf der Basis des Wertes auf, der an die TemplateSourceDirectory-Eigenschaft übergeben wurde. Der zurückgegebene URL ist für die Verwendung durch den Client bestimmt und enthält ggf. den Sitzungscookie.
|
| Validate
|
Weist alle Validierungssteuerelemente auf der Seite an, die Validierung durchzuführen
|
Tabelle 5.1 Eigenschaften und einige Methoden der Klasse Page
5.1 Der Lebenszyklus einer aspx-Seite
 
Beim ersten Aufruf einer aspx-Seite bemerken Sie im Browser eine gewisse Verzögerung. Eine aspx-Seite enthält verwalteten Code (managed Code), der von der Common Language Runtime verarbeitet wird. Beim ersten Aufruf tritt daher der Just-in-Time-Compiler in Aktion, der die Seite kompiliert. Das verursacht die Verzögerung. Bei weiteren Aufrufen steht die kompilierte Version bereits zur Verfügung. Weil der JIT-Compiler beim erneuten Aufruf einer Seite die Seite nicht nochmals kompilieren muss, werden weitere Aufrufe erheblich schneller abgearbeitet.
Jedes Mal, wenn eine aspx-Seite vom Webserver angefordert wird, muss der Webserver die Seite laden, die Werte initialisieren, die Seite ausführen, zum Browser senden und wieder entladen. Diese Schritte bilden den Lebenszyklus einer Seite. Bei einem Postback fallen zusätzliche Schritte an. Diese Arbeit fällt auf jeden Fall an, unabhängig davon, ob die Seite vorher noch kompiliert werden muss oder nicht.
5.1.1 Lebenszyklus beim ersten Aufruf
 
Beim ersten Aufruf einer Seite laufen folgende Schritte ab:
1. Init-Ereignis
Den Anfang bildet das Init-Ereignis. Hier werden solche Einstellungen initialisiert, die für die ganze Lebenszeit der eingehenden Anforderung benötigt werden.
2. Load-Ereignis
In dieser Phase wird der Baum aus Steuerelementen aufgebaut. Die erforderlichen Daten werden z. B. durch Datenbankabfragen ermittelt.
3. PreRender-Ereignis
Dieses Ereignis bietet die letzte Möglichkeit, vor der Ausgabe Änderungen vorzunehmen.
4. SaveViewState-Methode
Der ViewState-String wird erstellt.
5. Render-Methode
Die Ausgabe an den Client wird generiert.
6. Dispose-Methode
Ressourcen werden freigegeben.
7. UnLoad-Ereignis
Das Objekt wird entladen.
5.1.2 Lebenszyklus bei einem Postback
 
Bei einem Postback werden zusätzliche Schritte durchlaufen, so dass sich diese Abfolge ergibt:
1. Init-Ereignis
2. LoadViewState-Methode
Der ViewState wird geladen.
3. LoadPostData-Methode
Die Formulardaten werden verarbeitet.
4. Load-Ereignis
5. RaisePostDataChangedEvent-Methode
Wenn sich Statusänderungen zum vorhergehenden Status ergeben, wird diese Methode ausgeführt.
6. RaisePostBackEvent-Methode
Das Ereignis, das im Client den Postback verursacht hat, wird jetzt behandelt.
7. PreRender-Ereignis
8. SaveViewState-Methode
9. Render-Methode
10. Dispose-Methode
11. UnLoad-Ereignis
Die Ereignisse und Methoden, die den Lebenszyklus einer aspx-Seite bilden, können Sie mit selbst definierten Prozeduren überschreiben. In den meisten Fällen werden aber alle serverseitigen Aktionen in der Page_Load-Prozedur zusammengefasst. In diesem Stadium wird der Baum aus Steuerelementen, aus dem eine aspx-Seite besteht, komplett aufgebaut und Sie können entsprechende Einstellungen vornehmen. Diesen üblichen Weg geht auch name02.aspx.
Wenn Sie in der Page-Direktive das Attribut trace="true" hinzufügen, zeigt ASP.NET unterhalb der Seite zahlreiche Informationen an, die die Analyse der Seite ermöglichen. Der Abschnitt Überwachungsinformationen (siehe Abbildung 5.1) listet unter anderem diesen Lebenszyklus auf und verzeichnet für jeden Schritt die Dauer der Ausführung.
 Hier klicken, um das Bild zu Vergrößern
Abbildung 5.1 Mit trace="true« in der Page-Direktive wird der Lebenszyklus der Seite bis zur Stufe Render dargestellt.
5.1.3 In Page_Load die Validierung ausführen
 
Sub Page_Load (ByVal Sender As Object, _
ByVal E As EventArgs)
If IsPostBack Then
Page.Validate
If IsValid Then
meldung.Text = "Hallo, " & txtName.Value
End If
End If
End Sub
In der Beispielseite name02.aspx prüft die Prozedur Page_Load anhand der IsPostBack-Eigenschaft der Page-Klasse zunächst, ob ein Postback vorliegt. Wenn nicht, dann gibt es hier nichts zu tun, und die Seite wird einfach angezeigt.
Bei einem Postback veranlasst die Prozedur mit der Methode Page.Validate, dass die Validierungssteuerelemente der Seite die Überprüfungen durchführen. Anschließend kann die Page-Eigenschaft IsValid ausgewertet werden.
Wenn die Validierung erfolgreich war, wird die Hallo, Soundso-Meldung ausgegeben. Wenn die Validierung scheitert, dann ist innerhalb der Page_Load-Prozedur nichts mehr zu tun. Für die Darstellung der Fehlermeldung sorgt in diesem Fall das Validierungssteuerelement selbst.
Vielleicht kommen Sie auf die Idee, in der Page_Load-Prozedur auch den Else-Zweig auszufüllen, der ausgeführt wird, wenn die Seite nicht gültig ist, etwa so:
Sub Page_Load (ByVal Sender As Object, _
ByVal E As EventArgs)
If IsPostBack Then
Page.Validate
If IsValid Then
meldung.Text = "Hallo, " & txtName.Value
Else
meldung.Text = "Bitte einen Namen eingeben."
End If
End If
End Sub
| Achtung Wenn Sie diese Version testen, werden Sie aber mit hoher Wahrscheinlichkeit eine Überraschung erleben. Wenn Sie zunächst korrekt einen Namen, z. B. Hugo, eingeben, erscheint die Meldung Hallo, Hugo. Anschließend löschen Sie den Eintrag im Textfeld und klicken wieder auf OK. Danach steht zwar neben dem Eingabefeld in roter Schrift der Hinweis Bitte geben Sie hier Ihren Namen ein. Unter der OK-Schaltfläche steht aber noch immer die Begrüßung Hallo, Hugo. Wieso wurde der Else-Zweig bei der Validierung nicht durchlaufen und der Meldungstext entsprechend geändert?
|
Des Rätsels Lösung besteht darin, dass in diesem Fall noch gar kein Postback zum Server stattgefunden hat, sondern die clientseitige JavaScript-Funktion tätig gewesen ist, die das Validierungssteuerelement automatisch generiert hat. Diese clientseitige Funktion überprüft nur das ihr zugeordnete Steuerelement. Sie übersetzt aber nicht die Page_Load-Prozedur in JavaScript, was auch nicht funktionieren würde. Und falls die clientseitige Validierung scheitert, findet erst gar kein Postback statt.
 Hier klicken, um das Bild zu Vergrößern
Abbildung 5.2 Die clientseitige JavaScript-Routine wird vor dem Postback ausgeführt.
Solange JavaScript im Browser aktiviert ist, werden nur gültige Seiten zum Server geschickt, so dass der Zweig für ungültige Seiten innerhalb von Page_Load nie ausgeführt wird. Wenn Sie diesen Zweig dennoch ausführen möchten, müssten Sie im Browser JavaScript deaktivieren. Nur dann erreichen auch ungültige Seiten den Server, und er kann entsprechend reagieren.
In Kapitel 7, Validierung von Anwendereingaben, erhalten Sie genauere Informationen zu diesen Zusammenhängen. Ich habe bereits jetzt darauf hingewiesen, weil dieses undurchsichtige Verhalten am Anfang Verwirrung erzeugen kann.
|