32
287 Benutzersteuerelemente 288 Grundlagen 299 Das Steuerelement XmlNavBar 305 Dynamisches Laden und Cookies 315 Fragmentcaching 317 Vorschau: Benutzerdefinierte Steuerelemente Webformulare bringen die komponentenbasierte Programmierung ins Internet, da sie die Möglichkeit bieten, eine komplexe Darstellungs- und Verhaltenslogik in wiederverwendbaren Klassen von Server- steuerelementen zu kodieren. Klassen wie Calendar oder DataGrid bilden das Rückgrat von Web Forms und ermöglichen Entwicklern die Erstellung anspruchsvoller Webseiten mit einfachen Grund- kenntnissen in HTML und clientseitigem Scripting. Doch die komponentenbasierte Entwicklung mit ASP.NET hört bei Serversteuerelementen noch nicht auf. Es wird noch eine zweite Komponentenart unterstützt, die Benutzersteuerelemente. Dabei handelt es sich um individuell angepasste Steuerelemente aus HTML und serverseitigem Skript. Sie ermöglichen es, Funktionalität auf intuitive und leicht nachvollziehbare Weise zu erzielen und mehr- fach zu verwenden, ohne auf Server-Side Includes zurückgreifen zu müssen, die bei der ASP-Pro- grammierung sehr häufig eingesetzt werden. Mit diesem Mechanismus erfolgt die Erstellung wieder- verwendbarer ASP.NET-Komponenten viel einfacher als durch das Schreiben kompletter Serversteuerelemente. Jeder Programmierer, der mit dem Programmiermodell von Web Forms ver- traut ist, kann in kürzester Zeit einfache Benutzersteuerelemente erstellen und ausführen. Diese kön- nen dann, ähnlich wie DataGrids und andere Serversteuerelemente, durch deklarative Tags in Web- formularen instanziiert werden. Benutzersteuerelemente dienen im Wesentlichen den folgenden drei Zwecken: b Vereinfachung komplexer UI-Elemente, die in wiederverwendbare Komponenten umgewandelt werden b Erstellung dynamischer Seiten, die individuell für einzelne Benutzer angepasst werden können b Vereinfachung des Ausgabecachings auf Unterseitenebene. Damit lässt sich der statische Seiten- inhalt zwischenspeichern, während andere Teile der Seite dynamisch dargestellt werden. In diesem Kapitel werden die Merkmale, die Erstellung und der Gebrauch von Benutzersteuerele- menten behandelt und es wird erläutert, wie Sie von deren Verwendung profitieren können. Es wer- den praktische Beispiele für Benutzersteuerelemente vorgestellt, unter anderem eines zur Implemen- tierung von Web-Navigationsleisten. Außerdem lernen Sie, wie Sie Benutzersteuerelemente mit HTTP-Cookies kombinieren können, um personalisierte Inhalte zu erstellen. Schließlich erfahren

Benutzersteuerelemente - bücher.de · 2012-09-28 · Benutzersteuerelemente 291 Zum Testen des Login-Steuerelements benötigen Sie ein Webformular, zum Beispiel LoginPage1.aspx,

  • Upload
    others

  • View
    1

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Benutzersteuerelemente - bücher.de · 2012-09-28 · Benutzersteuerelemente 291 Zum Testen des Login-Steuerelements benötigen Sie ein Webformular, zum Beispiel LoginPage1.aspx,

287

Benutzersteuerelemente

288 Grundlagen299 Das Steuerelement XmlNavBar305 Dynamisches Laden und Cookies315 Fragmentcaching317 Vorschau: Benutzerdefinierte Steuerelemente

Webformulare bringen die komponentenbasierte Programmierung ins Internet, da sie die Möglichkeitbieten, eine komplexe Darstellungs- und Verhaltenslogik in wiederverwendbaren Klassen von Server-steuerelementen zu kodieren. Klassen wie Calendar oder DataGrid bilden das Rückgrat von WebForms und ermöglichen Entwicklern die Erstellung anspruchsvoller Webseiten mit einfachen Grund-kenntnissen in HTML und clientseitigem Scripting.

Doch die komponentenbasierte Entwicklung mit ASP.NET hört bei Serversteuerelementen nochnicht auf. Es wird noch eine zweite Komponentenart unterstützt, die Benutzersteuerelemente. Dabeihandelt es sich um individuell angepasste Steuerelemente aus HTML und serverseitigem Skript. Sieermöglichen es, Funktionalität auf intuitive und leicht nachvollziehbare Weise zu erzielen und mehr-fach zu verwenden, ohne auf Server-Side Includes zurückgreifen zu müssen, die bei der ASP-Pro-grammierung sehr häufig eingesetzt werden. Mit diesem Mechanismus erfolgt die Erstellung wieder-verwendbarer ASP.NET-Komponenten viel einfacher als durch das Schreiben kompletterServersteuerelemente. Jeder Programmierer, der mit dem Programmiermodell von Web Forms ver-traut ist, kann in kürzester Zeit einfache Benutzersteuerelemente erstellen und ausführen. Diese kön-nen dann, ähnlich wie DataGrids und andere Serversteuerelemente, durch deklarative Tags in Web-formularen instanziiert werden.

Benutzersteuerelemente dienen im Wesentlichen den folgenden drei Zwecken:

b Vereinfachung komplexer UI-Elemente, die in wiederverwendbare Komponenten umgewandeltwerden

b Erstellung dynamischer Seiten, die individuell für einzelne Benutzer angepasst werden können

b Vereinfachung des Ausgabecachings auf Unterseitenebene. Damit lässt sich der statische Seiten-inhalt zwischenspeichern, während andere Teile der Seite dynamisch dargestellt werden.

In diesem Kapitel werden die Merkmale, die Erstellung und der Gebrauch von Benutzersteuerele-menten behandelt und es wird erläutert, wie Sie von deren Verwendung profitieren können. Es wer-den praktische Beispiele für Benutzersteuerelemente vorgestellt, unter anderem eines zur Implemen-tierung von Web-Navigationsleisten. Außerdem lernen Sie, wie Sie Benutzersteuerelemente mitHTTP-Cookies kombinieren können, um personalisierte Inhalte zu erstellen. Schließlich erfahren

642.book Page 287 Monday, July 1, 2002 4:37 PM

Page 2: Benutzersteuerelemente - bücher.de · 2012-09-28 · Benutzersteuerelemente 291 Zum Testen des Login-Steuerelements benötigen Sie ein Webformular, zum Beispiel LoginPage1.aspx,

Kapitel 7288

Sie, wie Benutzersteuerelemente die Leistung von Anwendungen auf der Grundlage von Webformu-laren verbessern können.

Benutzersteuerelemente gehören zu den wichtigsten Elementen im Programmiermodell von WebForms. Sie sollten frühzeitig damit beginnen, alles über ihre Verwendung zu lernen.

GrundlagenBenutzersteuerelemente sind in ASCX-Dateien enthalten wie Webformulare in ASPX-Dateien. Die<form>-Tags in ASPX-Dateien kennzeichnen HTML-Formulare. In ASCX-Dateien finden sich dage-gen niemals <form>-Tags, da sie in bestehende Formulare eingefügt werden sollen. Im Folgendensehen Sie ein sehr einfaches Benutzersteuerelement:

<h1>Hello, world</h>

Nehmen Sie an, diese HTML-Anweisung sei in einer Datei namens Hello.ascx gespeichert. Nun wol-len Sie dieses Benutzersteuerelement in ein Webformular einfügen. Das geschieht mit Hilfe der fol-genden ASPX-Datei:

<%@ Register TagPrefix="user" TagName="Hello" src="Hello.ascx" %>

<html> <body> <form runat="server"> <user:Hello RunAt="server" /> </form> </body></html>

Bei der Ausführung stellt dieses Webformular in großen roten Buchstaben den Satz Hello, world dar.Verantwortlich dafür ist das im HTML eingebettete Benutzersteuerelement. Die Direktive @ Registeram Anfang der Datei sagt ASP.NET, was es zu tun hat, wenn es auf das Tag <user:Hello> stößt. DasAttribut Src bezeichnet die ASCX-Datei des Steuerelements. Mit TagName wird dem Steuerelementein Name (Hello) zugewiesen, während TagPrefix das Präfix des Namens (user) in einem Tagbestimmt, das die Instanz eines Steuerelements deklariert. Sie brauchen nicht unbedingt user als Prä-fix des Tags zu verwenden, sondern können genauso gut foo, den Namen Ihres Unternehmens oderein beliebiges anderes Wort wählen. In jeder ASPX-Datei mit einem Benutzersteuerelement mussjedoch die Direktive @ Register enthalten sein, die Name und Präfix des Tags bestimmt und dieASPX-Datei mit einer ASCX-Datei verknüpft.

Die Datei Hello.ascx ist so einfach, dass man sie fast nicht als Benutzersteuerelement bezeichnenkann. Es lassen sich mit ihr jedoch drei wichtige Prinzipien veranschaulichen:

b Benutzersteuerelemente werden in ASCX-Dateien gespeichert.

b Mit @ Register-Direktiven werden Tag-Namen und -Präfixe deklariert und ASCX-Dateien zuge-ordnet.

b Tags, die mit @ Register registriert werden, fügen Benutzersteuerelemente in Webformulare ein.

Aus dem hier gezeigten Beispiel ist nicht ersichtlich, dass Benutzersteuerelemente genauso wie Ser-versteuerelemente über Methoden, Eigenschaften und Ereignisse verfügen können. Sie könnenaußerdem wie ASPX-Dateien serverseitige Skripts enthalten. Im Verlauf dieses Kapitels wird einanspruchsvolleres Benutzersteuerelement vorgestellt, an dem diese und andere Merkmale deutlich

642.book Page 288 Monday, July 1, 2002 4:37 PM

Page 3: Benutzersteuerelemente - bücher.de · 2012-09-28 · Benutzersteuerelemente 291 Zum Testen des Login-Steuerelements benötigen Sie ein Webformular, zum Beispiel LoginPage1.aspx,

Benutzersteuerelemente 289

werden. Im Folgenden behandeln wir jedoch zunächst eine weitere wichtige Direktive namens @Control.

Die Direktive @ ControlASPX-Dateien enthalten häufig @ Page-Direktiven, die unter anderem Anweisungen für dasASP.NET-Kompilierungsmodul zur Verfügung stellen und bestimmte Eigenschaften von ASP.NETaktivieren oder deaktivieren. In ASCX-Dateien sind dagegen niemals @ Page-Direktiven enthalten,sondern @ Control-Direktiven.

@ Page- und @ Control-Direktiven haben viele Merkmale gemeinsam. Bis auf den Direktivennamensind sie fast völlig gleich. Zur Aktivierung der Debuggingunterstützung in einer ASCX-Datei könnenSie an den Anfang der Datei statt

<%@ Page Debug="true" %>

auch folgende Anweisung schreiben:

<%@ Control Debug="true" %>.

Zur Aktivierung der Debuggingunterstützung und zur Festlegung der Standardsprache für Inlineco-deblöcke können Sie Folgendes schreiben:

<%@ Control Debug="true" Language="C#" %>

@ Control-Direktiven können wie @ Page-Direktiven nur einmal in einer Datei auftauchen. Es istjedoch möglich, in einer @ Control-Direktive beliebig viele Attribute einzusetzen.

ASCX-Dateien können wie ASPX-Dateien @ Import- und @ Assembly-Direktiven enthalten. FallsSie in einer ASCX-Datei Typen aus Namespaces verwenden, die nicht standardmäßig importiert wer-den, oder Assemblytypen, für die ASP.NET nicht automatisch Verknüpfungen erstellt, können Siesich mit @ Import- und @ Assembly behelfen. Die Syntax in ASCX-Dateien für diese Direktiven istgenau dieselbe wie in ASPX-Dateien. In � Kapitel 5 wurden @ Import- und @ Assembly-Direktivenausführlich behandelt.

Ein erstes BenutzersteuerelementMit diesem Grundlagenwissen können Sie etwas anspruchsvollere Benutzersteuerelemente erstellen,zum Beispiel ein Login-Steuerelement zur Eingabe von Benutzernamen und Kennwort. Im Folgen-den erfahren Sie, welche Arbeitsschritte Sie dafür ausführen müssen. Das Endergebnis ist in Abbil-dung 7.1 dargestellt. Dieses Steuerelement dient einerseits der Eingabe des Benutzernamens und desKennworts, andererseits führt es auch eine einfache Validierung durch.

642.book Page 289 Monday, July 1, 2002 4:37 PM

Page 4: Benutzersteuerelemente - bücher.de · 2012-09-28 · Benutzersteuerelemente 291 Zum Testen des Login-Steuerelements benötigen Sie ein Webformular, zum Beispiel LoginPage1.aspx,

Kapitel 7290

Abbildung 7.1: Login-Benutzersteuerelement

Zur Erstellung des Login-Benutzersteuerelements legen Sie als Erstes eine Textdatei namensLoginControl1.ascx an. Als Nächstes geben Sie den in Fehler! Verweisquelle konnte nicht gefundenwerden. dargestellten Code ein, der drei Websteuerelemente deklariert: zwei TextBox-Steuerelementeund ein LinkButton-Steuerelement. In diesem Code wird eine HTML-Tabelle verwendet, um die Ele-mente auf der Seite auszurichten. Die TextBox-Steuerelemente stellen die Eingabefelder für denBenutzernamen und das Kennwort bereit. Mit Hilfe des LinkButton-Steuerelements wird das For-mular mit den Anmeldeeingaben an den Server übermittelt.

LoginControl1.ascx

<table cellpadding="4"> <tr> <td>User Name:</td> <td><asp:TextBox ID="MyUserName" RunAt="server" /></td> </tr> <tr> <td>Password:</td> <td><asp:TextBox ID="MyPassword" TextMode="password" RunAt="server" /></td> </tr> <tr> <td></td> <td><asp:LinkButton Text="Log In" RunAt="server" /></td> </tr></table>

Listing 7.1: Login-Steuerelement, Version 1

642.book Page 290 Monday, July 1, 2002 4:37 PM

Page 5: Benutzersteuerelemente - bücher.de · 2012-09-28 · Benutzersteuerelemente 291 Zum Testen des Login-Steuerelements benötigen Sie ein Webformular, zum Beispiel LoginPage1.aspx,

Benutzersteuerelemente 291

Zum Testen des Login-Steuerelements benötigen Sie ein Webformular, zum BeispielLoginPage1.aspx, dessen Quellcode Sie in Listing 7.2 sehen. Es deklariert mit der folgenden Anwei-sung eine Instanz des Login-Steuerelements:

<user:LoginControl RunAt="server" />

Die Direktive @ Register am Anfang der Datei bestimmt das Tag-Präfix user sowie den Tag-NamenLoginControl und verknüpft diese mit LoginControl1.ascx. Bei der Ausführung der Seite leitetASP.NET eine Klasse von System.Web.UI.UserControl ab, instanziiert sie und fügt ihr die Inhaltevon LoginControl1.ascx hinzu. Dann bildet es eine Instanz der abgeleiteten Klasse und setzt das ent-standene Objekt in die Steuerelementstruktur der Seite ein. (Die Steuerelementstruktur ist eine hie-rarchisch strukturierte Liste aller auf der Seite definierten Steuerelemente.) Schließlich werden diesesund alle anderen auf der Seite deklarierten Steuerelemente ausgeführt.

LoginPage1.aspx

<%@ Register TagPrefix="user" TagName="LoginControl" src="LoginControl1.ascx" %>

<html> <body> <h1>User Control Demo 1</h1> <hr> <form runat="server"> <user:LoginControl RunAt="server" /> </form> <hr> </body></html>

Listing 7.2: Testseite für LoginControl1

Wenn Sie LoginControl1.aspx nun in Ihrem Browser öffnen, wird die Seite aus Abbildung 7.1 darge-stellt. Das Login-Steuerelement ist darauf zu sehen, funktioniert jedoch noch nicht. Das liegt daran,dass kein serverseitiges Skript die Benutzereingaben in den Textfeldern lesen kann. Selbst wenn Siedem Login-Steuerelement eine ID zuweisen (zum Beispiel MyLogin), könnte die folgende Anwei-sung nicht kompiliert werden. MyUserName ist nämlich ein geschütztes Member der Klasse, dieASP.NET generiert, um das Login-Steuerelement darzustellen.

string name = MyLogin.MyUserName.Text;

Die Lösung besteht darin, als public deklarierte Eigenschaften hinzuzufügen, mit denen Skripts aufdie im Login-Steuerelement gekapselten Daten zugreifen können. Im nächsten Abschnitt erfahrenSie, wie Sie dabei vorgehen müssen.

642.book Page 291 Monday, July 1, 2002 4:37 PM

Page 6: Benutzersteuerelemente - bücher.de · 2012-09-28 · Benutzersteuerelemente 291 Zum Testen des Login-Steuerelements benötigen Sie ein Webformular, zum Beispiel LoginPage1.aspx,

Kapitel 7292

Hinzufügen von EigenschaftenBenutzersteuerelemente können wie Serversteuerelemente verschiedene Eigenschaften besitzen.Bereits bei der Erstellung eines Benutzersteuerelements sollten Sie in Betracht ziehen, auf welcheWeise es später individuell angepasst werden könnte. Sie können es anderen Entwicklern leichtermachen, indem Sie die Eigenschaften bereitstellen, mit denen die Erscheinung und das Verhalten desSteuerelements verändert werden können.

Es ist nicht schwer, eine Eigenschaft zu einem Benutzersteuerelement hinzuzufügen. Zu diesemZweck definieren Sie die Eigenschaft in einem <script>-Block der ASCX-Datei des Steuerelements.Zur Laufzeit fügt ASP.NET den in diesem Block enthaltenen Code der Klasse hinzu, die es zur Dar-stellung des Benutzersteuerelements ableitet. Alle im <script>-Block deklarierten Eigenschaften wer-den zu Membern dieser Klasse.

Die ASCX-Datei in Listing 7.3 fügt dem Login-Steuerelement drei als public deklarierte Eigenschaf-ten hinzu:

b Die Eigenschaft BackColor für die Hintergrundfarbe des Steuerelements

b Die Eigenschaft UserName zur Darstellung des Texts im Feld MyUserName

b Die Eigenschaft Password zur Darstellung des Texts im Feld MyPassword

Die Änderungen sind fett hervorgehoben, damit Sie die Unterschiede zwischen LoginControl1.ascxund LoginControl2.ascx besser erkennen können. Die Aufgabe der Eigenschaft BackColor bestehtlediglich im Lesen und Schreiben der BgColor-Eigenschaft der zugrunde liegenden Tabelle. Diese istdank des Attributs runat="server" im <table>-Tag eine Instanz von System.Web.UI.HtmlCont-rols.HtmlTable.

LoginControl2.ascx

<table id="MyTable" cellpadding="4" runat="server"> <tr> <td>User Name:</td> <td><asp:TextBox ID="MyUserName" RunAt="server" /></td> </tr> <tr> <td>Password:</td> <td><asp:TextBox ID="MyPassword" TextMode="password" RunAt="server" /></td> </tr> <tr> <td></td> <td><asp:LinkButton Text="Log In" RunAt="server" /></td> </tr></table>

<script language="C#" runat="server"> public string BackColor { get { return MyTable.BgColor; } set { MyTable.BgColor = value; } }

public string UserName { get { return MyUserName.Text; }

642.book Page 292 Monday, July 1, 2002 4:37 PM

Page 7: Benutzersteuerelemente - bücher.de · 2012-09-28 · Benutzersteuerelemente 291 Zum Testen des Login-Steuerelements benötigen Sie ein Webformular, zum Beispiel LoginPage1.aspx,

Benutzersteuerelemente 293

set { MyUserName.Text = value; } }

public string Password { get { return MyPassword.Text; } set { MyPassword.Text = value; } }</script>

Listing 7.3: Login-Steuerelement mit den Eigenschaften BackColor, UserName und Password

Das modifizierte Login-Steuerelement sehen Sie in Listing 7.4. Auch hier sind die Änderungen inFettdruck hervorgehoben. Beachten Sie das Attribut BackColor im Tag des Steuerelements. Es ver-ändert die Hintergrundfarbe, indem es die Eigenschaft BackColor des Steuerelements initialisiert.Außerdem wird in dieser Version durch ein serverseitiges Skript ein personalisierter Gruß auf derWebseite dargestellt. Zu diesem Zweck wird der Name verwendet, der im Textfeld für den Benutzer-namen eingegeben wurde (siehe Abbildung 7.2). Das Skript ruft den Inhalt der TextBox ab, indem esdie Eigenschaft UserName des Steuerelements liest. Wenn Sie wollen, können Sie UserName undPassword auch als Attribute im Tag des Steuerelements einsetzen, um die Textfelder vorab mit Textzu füllen.

LoginPage2.aspx

<%@ Register TagPrefix="user" TagName="LoginControl" src="LoginControl2.ascx" %>

<html> <body> <h1>User Control Demo 2</h1> <hr> <form runat="server"> <user:LoginControl ID="MyLogin" BackColor="#ccccff" RunAt="server" /> </form> <hr> <h3><asp:Label ID="Output" RunAt="server" /></h3> </body></html>

<script language="C#" runat="server"> void Page_Load (Object sender, EventArgs e) { if (IsPostBack) Output.Text = "Hello, " + MyLogin.UserName; }</script>

Listing 7.4: Die Testseite für LoginControl2

So weit, so gut. Das Login-Steuerelement kann nun benutzt werden. Allerdings fängt das serverseitigeSkript das Postback auf, das beim Anklicken der Schaltfläche Log In generiert wird, indem es dasPage.Load-Ereignis verarbeitet, das durch das Postback ausgelöst wird. Eine andere Lösung wird

642.book Page 293 Monday, July 1, 2002 4:37 PM

Page 8: Benutzersteuerelemente - bücher.de · 2012-09-28 · Benutzersteuerelemente 291 Zum Testen des Login-Steuerelements benötigen Sie ein Webformular, zum Beispiel LoginPage1.aspx,

Kapitel 7294

dem Programmiermodell von Web Forms besser gerecht: Dabei wird das Ereignis vom Login-Steuer-element selbst ausgelöst, wenn der Benutzer auf die Schaltfläche Log In klickt. Im nächstenAbschnitt erfahren Sie, wie Sie diese Version erstellen können.

Abbildung 7.2: LoginControl2 in einem Webformular

Hinzufügen von EreignissenEreignisse werden zu Benutzersteuerelementen hinzugefügt, indem man sie in einem <script>-Blockdeklariert. Wie die in Skriptblöcken deklarierten Eigenschaften werden auch Ereignisse zu Membernder Klasse, die ASP.NET von UserControl zur Darstellung des Steuerelements ableitet.

Listing 7.5 zeigt eine dritte Variante des Benutzersteuerelements. In dieser Version wird ein Ereignisnamens Login deklariert. Außerdem wird die Schaltfläche Log In mit einem Click-Handler namensOnLoginButtonClick verbunden, der ein Login-Ereignis auslöst, wenn alle Textfelder ausgefüllt sind.Die abgeänderte Testseite in Listing 7.6 fügt dem Tag <user:LoginControl> ein OnLogin-Attributhinzu. Es reagiert auf Login-Ereignisse mit der Aktivierung von OnLoginUser. Sie können das For-mular testen, indem Sie einen Benutzernamen und ein Kennwort eingeben und auf die SchaltflächeLog In klicken. Der Benutzername sollte daraufhin unten auf der Seite erscheinen. Dieses Formularist besser konzipiert als das aus dem vorangegangenen Abschnitt. Hier wird die Begrüßung nur dannangezeigt, wenn der Benutzer auf die Schaltfläche klickt, selbst wenn andere in der Seite enthalteneSteuerelemente Postbacks auslösen.

LoginControl3.ascx

<table id="MyTable" cellpadding="4" runat="server"> <tr>

642.book Page 294 Monday, July 1, 2002 4:37 PM

Page 9: Benutzersteuerelemente - bücher.de · 2012-09-28 · Benutzersteuerelemente 291 Zum Testen des Login-Steuerelements benötigen Sie ein Webformular, zum Beispiel LoginPage1.aspx,

Benutzersteuerelemente 295

<td>User Name:</td> <td><asp:TextBox ID="MyUserName" RunAt="server" /></td> </tr> <tr> <td>Password:</td> <td><asp:TextBox ID="MyPassword" TextMode="password" RunAt="server" /></td></tr> <tr> <td></td> <td><asp:LinkButton Text="Log In" OnClick="OnLoginButtonClicked" RunAt="server" /></td> </tr></table>

<script language="C#" runat="server"> public string BackColor { get { return MyTable.BgColor; } set { MyTable.BgColor = value; } }

public string UserName { get { return MyUserName.Text; } set { MyUserName.Text = value; } }

public string Password { get { return MyPassword.Text; } set { MyPassword.Text = value; } }

public event EventHandler Login;

void OnLoginButtonClicked (Object sender, EventArgs e) { if (Login != null && UserName.Length > 0 && Password.Length > 0) Login (this, new EventArgs ()); // Login-Ereignis auslösen }</script>

Abbildung 7.3: Login-Steuerelement mit Login-Ereignis

LoginPage3.aspx

<%@ Register TagPrefix="user" TagName="LoginControl" src="LoginControl3.ascx" %>

<html> <body> <h1>User Control Demo 3</h1> <hr> <form runat="server">

642.book Page 295 Monday, July 1, 2002 4:37 PM

Page 10: Benutzersteuerelemente - bücher.de · 2012-09-28 · Benutzersteuerelemente 291 Zum Testen des Login-Steuerelements benötigen Sie ein Webformular, zum Beispiel LoginPage1.aspx,

Kapitel 7296

<user:LoginControl ID="MyLogin" BackColor="#ccccff"OnLogin="OnLoginUser" RunAt="server" />

</form><hr>

<h3><asp:Label ID="Output" RunAt="server" /></h3> </body></html>

<script language="C#" runat="server"> void OnLoginUser (Object sender, EventArgs e) { Output.Text = "Hello, " + MyLogin.UserName; }</script>

Listing 7.5: Testseite für LoginControl3

Verwenden von Code-Behind bei BenutzersteuerelementenDank der hinzugefügten Eigenschaften und Ereignisse ist das Login-Steuerelement nun eine eigen-ständige Komponente. Im letzten Arbeitsschritt verwenden wir die Code-Behind-Programmierung,um den C#-Code aus der ASCX-Datei zu entfernen und in eine DLL zu kompilieren. Gleichzeitigerweitern wir das Login-Steuerelement ein wenig und lassen es einen einfachen Validierungscode fürden Benutzernamen und das Kennwort ausführen. Außerdem wird ein benutzerdefinierter Delegatnamens LoginEventHandler bestimmt. Er nimmt den Parameter LoginEventArgs an, der anzeigt, obdie Benutzeranmeldung gültig ist. LoginEventArgs ist ein benutzerdefinierter Datentyp, den wir derDLL mit der Code-Behind-Klasse hinzufügen.

Den abgeänderten Quellcode für das Login-Steuerelement sehen Sie in Listing 7.7. Die ASCX-Dateienthält das HTML für das Steuerelement und die Direktive @ Control, deren Inherits-Attribut dieBasisklasse des Login-Steuerelements bezeichnet. Normalerweise würde ASP.NET die Klasse desSteuerelements von UserControl ableiten. Hier erfolgt die Ableitung jedoch von LoginBase, welcheihrerseits von UserControl abgeleitet ist.

Die Datei LoginBase.cs enthält den Quellcode für die Klasse LoginBase. LoginBase deklariert Fel-der namens MyTable, MyUserName und MyPassword, die den Steuerelementen derselben Namenin der ASCX-Datei zugeordnet werden. Außerdem deklariert diese Klasse einen benutzerdefiniertenDelegaten namens LoginEventHandler. Wenn man auf die Schaltfläche Log In klickt, löst Login-Base ein Login-Ereignis aus, das von einem LoginEventArgs-Objekt begleitet wird. Die IsValid-Eigenschaft dieses Objekts lautet true bei einer gültigen Anmeldung und false bei einer ungültigen.Zur Überprüfung der Gültigkeit der Benutzereingaben vergleicht OnLoginButtonClicked diese mitdem Benutzernamen jeffpro und dem Kennwort imbatman. In der Praxis würden die Eingaben mitden Inhalten einer Back-End-Datenbank (oder zumindest einer XML-Datei) abgeglichen werden.Das Prinzip ist jedoch das gleiche.

LoginControl4.ascx

<%@ Control Inherits="LoginBase" %>

<table id="MyTable" cellpadding="4" runat="server"> <tr> <td>User Name:</td> <td><asp:TextBox ID="MyUserName" RunAt="server" /></td>

642.book Page 296 Monday, July 1, 2002 4:37 PM

Page 11: Benutzersteuerelemente - bücher.de · 2012-09-28 · Benutzersteuerelemente 291 Zum Testen des Login-Steuerelements benötigen Sie ein Webformular, zum Beispiel LoginPage1.aspx,

Benutzersteuerelemente 297

</tr> <tr> <td>Password:</td> <td><asp:TextBox ID="MyPassword" TextMode="password" RunAt="server" /></td> </tr> <tr> <td></td> <td><asp:LinkButton Text="Log In" OnClick="OnLoginButtonClicked" RunAt="server" /></td> </tr></table>

LoginBase.cs

using System;using System.Web.UI;using System.Web.UI.HtmlControls;using System.Web.UI.WebControls;

public class LoginEventArgs{ private bool LoginValid;

public LoginEventArgs (bool IsValid) { LoginValid = IsValid; }

public bool IsValid { get { return LoginValid; } }}

public class LoginBase : UserControl{ protected HtmlTable MyTable; protected TextBox MyUserName; protected TextBox MyPassword; public string BackColor { get { return MyTable.BgColor; } set { MyTable.BgColor = value; } }

public string UserName { get { return MyUserName.Text; } set { MyUserName.Text = value; } }

public string Password { get { return MyPassword.Text; } set { MyPassword.Text = value; }

642.book Page 297 Monday, July 1, 2002 4:37 PM

Page 12: Benutzersteuerelemente - bücher.de · 2012-09-28 · Benutzersteuerelemente 291 Zum Testen des Login-Steuerelements benötigen Sie ein Webformular, zum Beispiel LoginPage1.aspx,

Kapitel 7298

}

public delegate void LoginEventHandler (Object sender, LoginEventArgs e);

public event LoginEventHandler Login;

public void OnLoginButtonClicked (Object sender, EventArgs e) { if (Login != null) { bool IsValid = (UserName.ToLower () == "jeffpro" && Password == "imbatman"); Login (this, new LoginEventArgs (IsValid)); } }}

Listing 7.6: Login-Steuerelement mit Code-Behind

Die Testseite in Listing 7.8 reagiert auf Login-Ereignisse mit der Darstellung einer Begrüßung, wenndie Anmeldung gültig war, bzw. mit einer Fehlermeldung bei ungültigen Eingaben. Vor der Ausfüh-rung von LoginPage4.aspx müssen Sie LoginBase.cs kompilieren und die entstandene DLL im Ver-zeichnis bin des Anwendungsstamms ablegen, wo ASP.NET sie finden kann. Mit dem folgendenBefehl wird die DLL erstellt:

csc /t:library LoginBase.cs

Wenn Sie LoginPage4.aspx aus dem Verzeichnis wwwroot heraus ausführen, müssen Sie die DLLunter wwwroot\bin ablegen.

LoginPage4.aspx

<%@ Register TagPrefix="user" TagName="LoginControl" src="LoginControl4.ascx" %>

<html> <body> <h1>User Control Demo 4</h1> <hr> <form runat="server"> <user:LoginControl ID="MyLogin" BackColor="#ccccff" OnLogin="OnLoginUser" RunAt="server" /> </form> <hr> <h3><asp:Label ID="Output" RunAt="server" /></h3> </body></html>

<script language="C#" runat="server"> void OnLoginUser (Object sender, LoginEventArgs e) { if (e.IsValid) Output.Text = "Hello, " + MyLogin.UserName; else {

642.book Page 298 Monday, July 1, 2002 4:37 PM

Page 13: Benutzersteuerelemente - bücher.de · 2012-09-28 · Benutzersteuerelemente 291 Zum Testen des Login-Steuerelements benötigen Sie ein Webformular, zum Beispiel LoginPage1.aspx,

Benutzersteuerelemente 299

Output.Text = "Invalid login"; MyLogin.UserName = ""; MyLogin.Password = ""; } }</script>

Listing 7.7: Testseite für LoginControl4

Das Steuerelement XmlNavBarAm linken Rand vieler Seiten im Internet befindet sich häufig eine Liste mit Verknüpfungen zu ande-ren Seiten. Dieses UI-Element wird als Navigationsleiste bezeichnet. Navigationsleisten sind aufWebseiten so häufig anzutreffen wie Menüs in Windows-Anwendungen. Sie werden idealerweise alsBenutzersteuerelemente implementiert, da sie gewöhnlich nicht nur einmal auftauchen, sonderninnerhalb der Website mehrmals wiederholt werden. Eine als Benutzersteuerelement ausgeführteNavigationsleiste braucht nicht auf jeder Seite als individuelles Objekt wiederholt zu werden, son-dern wird bei Bedarf von einem einfachen Tag erstellt. Wenn Sie alle Navigationsleisten einer Websiteaktualisieren möchten, brauchen Sie nur eine einzige Quellcodedatei zu verändern.

Die Webseite in Abbildung 7.3 enthält ein Navigationsleisten-Benutzersteuerelement, das ich Xml-NavBar genannt habe. Es ruft die Elemente, die es anzeigt, und die URLs für ihre Verknüpfungen auseiner XML-Datei ab. Außerdem verfügt es über Eigenschaften zur Steuerung seiner Breite und Höhe,der Vorder- und Hintergrundfarben und der Schriftart, in der die Elemente dargestellt werden. Xml-NavBar unterstützt sogar Mouseover-Effekte. Mit dem Attribut MouseOverColor im Tag des Steuer-elements werden die Elemente in der Navigationsleiste in der entsprechenden Farbe hervorgehoben,wenn man den Mauszeiger über sie bewegt.

Die Navigationsleiste in Abbildung 7.3 enthält vier Elemente. Wenn Sie eines davon anklicken, wer-den Sie auf die entsprechende Webseite weitergeleitet: News.aspx, Sports.aspx, Stocks.aspx oderWeather.aspx. Alle vier Seiten finden Sie auf der CD-ROM zu diesem Buch. Da sie jedoch fast iden-tisch sind, wird in diesem Abschnitt (in Listing 7.9) nur eine von ihnen vorgestellt. Mit der Direktive@ Register werden das Steuerelement und das Tag <user:XmlNavBar> zu seiner Erstellung regist-riert. Das Attribut XmlSrc dient zur Bezeichnung der XML-Datei, aus der das Steuerelement seineInhalte bezieht. Die einzelnen Einträge werden in der XML-Datei durch Item-Elemente dargestellt.Die Elemente Name und Link bestimmen den Text und die Verknüpfungsadresse für jedes Element.Da sich das Steuerelement XmlNavBar aus einer externen Datei selbst konfiguriert, können Sie esauf jeder Seite individuell anpassen, wenn Sie es mit unterschiedlichen XML-Dateien verbinden. DieXML-Datei Links.xml für dieses Beispiel sehen Sie in Listing 7.10.

642.book Page 299 Monday, July 1, 2002 4:37 PM

Page 14: Benutzersteuerelemente - bücher.de · 2012-09-28 · Benutzersteuerelemente 291 Zum Testen des Login-Steuerelements benötigen Sie ein Webformular, zum Beispiel LoginPage1.aspx,

Kapitel 7300

Abbildung 7.4: Webseite mit XmlNavBar-Benutzersteuerelement.

News.aspx

<%@ Register TagPrefix="user" TagName="XmlNavBar" Src="XmlNavBar.ascx" %>

<html> <body> <form runat="server"> <table width="100%" height="100%"> <tr height="48"> <td bgcolor="teal" align="center" colspan="2"> <span style="color: white; font-family: verdana; font-size: 24pt; font-weight: bold"> News </span> </td> </tr> <tr> <td width="128" valign="top" bgcolor="royalblue"> <user:XmlNavBar XmlSrc="Links.xml" ForeColor="white" Font-Name="verdana" Font-Size="10pt" Font-Bold="true" MouseOverColor="black" RunAt="server" /> </td> <td align="center" valign="center"> No news is good news </td> </tr>

642.book Page 300 Monday, July 1, 2002 4:37 PM

Page 15: Benutzersteuerelemente - bücher.de · 2012-09-28 · Benutzersteuerelemente 291 Zum Testen des Login-Steuerelements benötigen Sie ein Webformular, zum Beispiel LoginPage1.aspx,

Benutzersteuerelemente 301

</table> </form> </body></html>

Abbildung 7.5: Webformular mit XmlNavBar

Links.xml

<?xml version="1.0"><Items> <Item> <Text>News</Text> <Link>News.aspx</Link> </Item> <Item> <Text>Sports</Text> <Link>Sports.aspx</Link> </Item> <Item> <Text>Stocks</Text> <Link>Stocks.aspx</Link></Item> <Item> <Text>Weather</Text> <Link>Weather.aspx</Link> </Item></Items>

Abbildung 7.6: XML-Quelldatei zur Konfigurierung eines XmlNavBar-Benutzersteuerelements

XmlNavBar wird im Quellcode der Datei XmlNavBar.ascx definiert (siehe Listing 7.11). DieseDatei enthält lediglich eine einzige HTML-Zeile:

<asp:Table ID="MyTable" RunAt="server" />

Alles andere erledigt ein serverseitiges Skript. Mit Hilfe von Page_Load wird XmlNavBar zur Lauf-zeit erstellt, indem Zeilen zur Tabelle MyTable hinzugefügt werden. (Ein Benutzersteuerelement istzwar keine »Seite« im eigentlichen Sinn, doch Page_Load fungiert als Handler für das Ereignis, dasbeim Laden des Steuerelements ausgelöst wird.) Jede Zeile enthält eine Zelle, in der sich der Text fürein Element befindet. Er steht zwischen den HTML-Tags <a> und </a>, die auf den URL des Ele-ments verweisen. Im Folgenden sehen Sie ein typisches Beispiel:

<a href="News.aspx" onmouseover="defcolor=this.style.color;this.style.color='Black'" onmouseout="this.style.color=defcolor"style="text-decoration: none; font-family: verdana; font-size 10pt;font-weight: bold; color: White">News</a>

Das Href-Attribut stammt aus einem der Link-Elemente in der XML-Datei. Das Attribut MouseOver-Color im Tag <user:XmlNavBar> wird in Form der Attribute OnMouseOver und OnMouseOutumgesetzt. Sie bestimmen, welche Farbe die Elemente annehmen, wenn man den Mauszeiger über sie

642.book Page 301 Monday, July 1, 2002 4:37 PM

Page 16: Benutzersteuerelemente - bücher.de · 2012-09-28 · Benutzersteuerelemente 291 Zum Testen des Login-Steuerelements benötigen Sie ein Webformular, zum Beispiel LoginPage1.aspx,

Kapitel 7302

bewegt. Weitere Attribute sind Font und ForeColor, die als Style-Attribute in <a>-Tags wiedergegebenwerden.

XmlNavBar liest XML-Dateien auf die gleiche Weise wie die Datei Converter.aspx aus � Kapitel 5:Sie liest sie in ein DataSet ein und geht nacheinander alle Zeilen durch. Dank DataSet.ReadXmlkönnen Sie das komplizierte Parsen einer XML-Datei durch einen einfachen Methodenaufruf erset-zen. Nachdem die Datei einmal eingelesen wurde, kann XmlNavBar die Namen und URLs der dar-gestellten Einträge abrufen, indem es die Elementnamen in der XML-Datei als Indizes für die Zeilenvon DataSet benutzt.

XmlNavBar kann Teile seiner Ausgabe an den Browser anpassen, von dem die Anforderung kommt.Ein XmlNavBar-Steuerelement gibt nicht blindlings OnMouseOver- und OnMouseOut-Attributeaus, wenn in seinem Tag ein MouseOverColor-Attribut enthalten ist, sondern nur dann, wenn es sichbei dem anfragenden Browser um Internet Explorer 4 oder höher handelt. Mouseover-Effekte sind inNavigator sehr schwierig zu erstellen und funktionieren auch nicht in älteren Versionen von InternetExplorer. Im Folgenden sehen Sie, wie XmlNavBar den Typ und die Version des Browsers feststellenkann:

if (Request.Browser.Type.ToUpper ().IndexOf ("IE") > -1 && Request.Browser.MajorVersion >= 4) { . . .}

Webserver beziehen die Information über den Browsertyp und die Versionsnummer aus den User-Agent-Headern in HTTP-Anforderungen. ASP.NET überprüft die User-Agent-Header durch dieEigenschaft Browser des Request-Objekts. Type, MajorVersion, MinorVersion, JavaScript, Cookiesund andere Browser-Eigenschaften übermitteln Informationen über den Browser, von dem dieAnfrage stammt, und die von ihm unterstützten Funktionen. Eine vollständige Liste aller Browser-Eigenschaften finden Sie in der Dokumentation zu System.Web.Http.BrowserCapabilities im .NETFramework SDK.

Interessant ist außerdem, wie XmlNavBar.ascx die Eigenschaft Font implementiert. Font dient ledig-lich als Container für die Untereigenschaften Name, Size und Weight. Wenn ASP.NET auf ein Attri-but wie das folgende stößt:

Font-Name="verdana"

generiert es einen Code, der folgendermaßen aussieht:

ctrl.Font.Name="verdana";

Font muss dabei die Instanz eines Typs sein, der eine Zeichenfolgeneigenschaft namens Name imple-mentiert. In der Datei XmlNavBar.ascx wird Font folgendermaßen implementiert:

MyFontInfo MyFont = new MyFontInfo (); . .public MyFontInfo Font{ get { return MyFont; }

642.book Page 302 Monday, July 1, 2002 4:37 PM

Page 17: Benutzersteuerelemente - bücher.de · 2012-09-28 · Benutzersteuerelemente 291 Zum Testen des Login-Steuerelements benötigen Sie ein Webformular, zum Beispiel LoginPage1.aspx,

Benutzersteuerelemente 303

set { MyFont = value; }}

Mit MyFontInfo, das ebenfalls in der Datei XmlNavBar.ascx definiert ist, wird Name auf folgendeWeise implementiert:

string FontName; . . .public string Name{ get { return FontName; } set { FontName = value; }}

Die Eigenschaft Font, die Websteuerelemente von WebControl erben, wird auf ganz ähnliche Weiseimplementiert. Mit diesem Wissen können Sie nun bei Bedarf jederzeit Eigenschaften mit Untereigen-schaften schreiben.

Als ich XmlNavBar erstellte, wollte ich ursprünglich gar keine Klasse MyFontInfo schreiben, son-dern die Klasse FontInfo aus der .NET Framework-Klassenbibliothek (System.Web.UI.WebCont-rols.FontInfo) verwenden. FontInfo kann jedoch nicht direkt instanziiert werden, da sie über keinenöffentlichen Konstruktor verfügt. Aus diesem Grund habe ich meine eigene Version geschrieben undin die Datei XmlNavBar eingefügt.

XmlNavBar.ascx

<%@ Import Namespace="System.Data" %><%@ Import Namespace="System.Drawing" %>

<asp:Table ID="MyTable" RunAt="server" />

<script language="C#" runat="server"> string MyXmlSrc; Color MyBackColor; Color MyForeColor; Color MyMouseOverColor; MyFontInfo MyFont = new MyFontInfo ();

public string XmlSrc { get { return MyXmlSrc; } set { MyXmlSrc = value; } }

public Color BackColor { get { return MyBackColor; } set { MyBackColor = value; } }

public Color ForeColor {

642.book Page 303 Monday, July 1, 2002 4:37 PM

Page 18: Benutzersteuerelemente - bücher.de · 2012-09-28 · Benutzersteuerelemente 291 Zum Testen des Login-Steuerelements benötigen Sie ein Webformular, zum Beispiel LoginPage1.aspx,

Kapitel 7304

get { return MyForeColor; } set { MyForeColor = value; } }public Color MouseOverColor { get { return MyMouseOverColor; } set { MyMouseOverColor = value; } }

public MyFontInfo Font { get { return MyFont; } set { MyFont = value; } }

void Page_Load (Object sender, EventArgs e) { if (MyXmlSrc != null) { DataSet ds = new DataSet (); ds.ReadXml (Server.MapPath (MyXmlSrc));

foreach (DataRow item in ds.Tables[0].Rows) { TableRow row = new TableRow (); TableCell cell = new TableCell ();

StringBuilder builder = new StringBuilder (); builder.Append ("<a href=\""); builder.Append (item["Link"]); builder.Append ("\" ");

if (MyMouseOverColor != Color.Empty && Request.Browser.Type.ToUpper ().IndexOf ("IE") > -1 && Request.Browser.MajorVersion >= 4) { builder.Append ("onmouseover=\"" + "defcolor=this.style.color; " + "this.style.color=\'"); builder.Append (MyMouseOverColor.Name); builder.Append ("\'\" onmouseout=\"" + "this.style.color=defcolor\" "); }

builder.Append ("style=\"text-decoration: none; ");

if (MyFont.Name != null) { builder.Append ("font-family: "); builder.Append (MyFont.Name); builder.Append ("; "); }

if (MyFont.Size != FontUnit.Empty) { builder.Append ("font-size: "); builder.Append (MyFont.Size.ToString ()); builder.Append ("; "); }

if (MyFont.Bold)

642.book Page 304 Monday, July 1, 2002 4:37 PM

Page 19: Benutzersteuerelemente - bücher.de · 2012-09-28 · Benutzersteuerelemente 291 Zum Testen des Login-Steuerelements benötigen Sie ein Webformular, zum Beispiel LoginPage1.aspx,

Benutzersteuerelemente 305

builder.Append ("font-weight: bold; ");

if (MyForeColor != Color.Empty) { builder.Append ("color: "); builder.Append (MyForeColor.Name); }

builder.Append ("\">"); builder.Append (item["Text"]); builder.Append ("</a>");

cell.Text = builder.ToString (); row.Cells.Add (cell); MyTable.Rows.Add (row); }

if (MyBackColor != Color.Empty) MyTable.BackColor = MyBackColor; } }

public class MyFontInfo { string FontName; FontUnit FontSize; bool FontBold = false;

public string Name { get { return FontName; } set { FontName = value; } }

public FontUnit Size { get { return FontSize; } set { FontSize = value; } }

public bool Bold { get { return FontBold; } set { FontBold = value; } } }</script>

Listing 7.8: XmlNavBar-Benutzersteuerelement

Dynamisches Laden und CookiesEs ist relativ leicht, Benutzersteuerelemente durch das Hinzufügen von Tags in ASPX-Dateien dekla-rativ zu erstellen. Sie können jedoch auch programmatisch erstellt werden. Diese Prozedur bezeich-net man als dynamisches Laden. Die Methode LoadControl der Klasse Page lädt Benutzersteuerele-

642.book Page 305 Monday, July 1, 2002 4:37 PM

Page 20: Benutzersteuerelemente - bücher.de · 2012-09-28 · Benutzersteuerelemente 291 Zum Testen des Login-Steuerelements benötigen Sie ein Webformular, zum Beispiel LoginPage1.aspx,

Kapitel 7306

mente zur Laufzeit. Sie verwendet dazu als Eingabe den Namen einer ASCX-Datei und gibt einenallgemeinen Control-Verweis zurück, der das geladene Steuerelement repräsentiert. Im folgendenBeispiel entfällt das Tag <user:XmlNavBar>, da XmlNavBar dynamisch geladen wird:

Control navbar = LoadControl ("XmlNavBar.ascx");Controls.Add (navbar);

Die erste Anweisung lädt das Steuerelement. Die zweite fügt es in die Seite ein, indem sie Add für dieControls-Auflistung der Seite aufruft. In der Praxis ist es selten so einfach, ein dynamisch geladenesSteuerelement in eine Seite einzufügen. Gewöhnlich wird Add für die Controls-Auflistung einerTabellenzelle oder eines <span>-Elements aufgerufen, um festzulegen, an welcher Stelle das Steuer-element auf der Seite erscheint. Wenn der Container außerdem noch andere Steuerelemente enthält,können Sie statt Add auch AddAt verwenden, um zu bestimmen, an welcher Stelle der Control-Auf-listung des Containers das neue Steuerelement eingefügt werden soll.

LoadControl erleichtert das dynamische Laden ungemein. Der einzige Nachteil besteht darin, dassSie mit dem zurückgegebenen Control-Verweis nicht auf die in der ASCX-Datei definierten Metho-den, Eigenschaften und Ereignisse zugreifen können. Der folgende Code lässt sich zum Beispiel nichtkompilieren, da XmlSrc ein Member von Control ist:

Control navbar = LoadControl ("XmlNavBar.ascx");// Versucht, das Steuerelement mit einer XML-Quelldatei zu verbindennavbar.XmlSrc = "Links.xml"; // Kann nicht kompiliert werden!

Dieses Beispiel funktioniert, wenn der Control-Verweis in einen XmlNavBar-Verweis umgewandeltwird:

XmlNavBar_ascx navbar = (XmlNavBar_ascx) LoadControl ("XmlNavBar.ascx");// Versucht, das Steuerelement mit einer XML-Quelldatei zu verbindennavbar.XmlScr = "Links.xml"; // Es funktioniert!

Bei XmlNavBar_ascx handelt es sich um den Namen der von ASP.NET erzeugten Klasse, die für dasSteuerelement XmlNavBar steht. An die Stelle der Dateierweiterung wird einfach _ascx gesetzt.Wenn Sie die Klasse lieber selbst benennen möchten, können Sie die Direktive @ Control in dieASCX-Datei einfügen:

<%@ Control ClassName="XmlNavBarControl" %>

Der Code zum Laden und Initialisieren des Steuerelements sieht dann folgendermaßen aus:

XmlNavBarControl navbar = (XmlNavBarControl) LoadControl ("XmlNavBar.ascx");navbar.XmlSrc = "Links.xml";

Unabhängig davon, ob Sie den Klassennamen selbst bestimmen oder die Standardnamen verwenden,müssen Sie das Steuerelement mit der Direktive @ Register registrieren, wenn Sie den Rückgabewertvon LoadControl konvertieren. Ansonsten gibt der Compiler die Fehlermeldung aus, dass nicht ineinen undefinierten Typ umgewandelt werden kann.

Sie möchten jetzt sicher wissen, warum Sie Benutzersteuerelemente dynamisch laden sollten. DieAntwort lautet, dass Sie Webformulare auf diese Weise sehr gut an individuelle Benutzerwünscheanpassen können. Nehmen Sie an, Sie bieten Ihren Benutzern die Möglichkeit, einen Börsentickerauf der Homepage Ihres Unternehmens anzeigen zu lassen. In diesem Fall könnten Sie den Ticker als

642.book Page 306 Monday, July 1, 2002 4:37 PM

Page 21: Benutzersteuerelemente - bücher.de · 2012-09-28 · Benutzersteuerelemente 291 Zum Testen des Login-Steuerelements benötigen Sie ein Webformular, zum Beispiel LoginPage1.aspx,

Benutzersteuerelemente 307

Benutzersteuerelement implementieren und dieses zur Laufzeit nur für solche Benutzer laden, dieden Ticker sehen wollen. Andere Benutzer, die diese Option nicht interessiert, werden dann nichtdavon belästigt.

CookiesWenn Sie Webseiten mit Unterstützung für individuelle Benutzerwünsche schreiben, müssen Sie dieInformationen über die bevorzugten Einstellungen irgendwo speichern. HTTP ist ein zustandslosesProtokoll. Wenn ein Benutzer Ihre Website betrachtet, kommt auf dem Webserver lediglich eineAbfolge verschiedener HTTP-Anforderungen an, die von irgendeiner IP-Adresse versandt werden.Sehr wahrscheinlich mischen sich in diese Anfragen auch noch die von anderen IP-Adressen. Benut-zereinstellungen müssen daher auf dem Server gespeichert werden, und Sie brauchen eine Methode,mit der sie diese den eingehenden HTTP-Anforderungen zuordnen können. Eine andere Möglichkeitbesteht darin, die Benutzereinstellungen direkt in den einzelnen Anforderungen zu kodieren. Zu die-sem Zweck gibt es Cookies.

Cookies sind kleine Codefragmente, die vom Browser mit jeder Anforderung an den Webservergesendet werden. Sie werden im HTTP-Header Cookie transportiert. Im Folgenden sehen Sie eineHTTP-Anforderung, die ein Cookie enthält:

GET /mypage.html HTTP/1.1Accept: */* . . .User-Agent: Mozilla/4.0.(compatible; MSIE.6.0; Windows NT 5.1)Host: www.wintellect.comCookie: FavoriteColor=Blue

Cookies haben Namen und Werte. In dem gezeigten Beispiel lautet der Name des Cookies Favorite-Color und sein Wert Blue. Ein Browser kann mehrere Cookies auf einmal übermitteln, indem er siein eine durch Semikola getrennte Liste schreibt:

Cookie: FavoriteColor=Blue; FavoriteNumber=3

Auf zahlreichen Websites werden Cookies verwendet, um Benutzer zu identifizieren, die die Seitebereits einmal besucht haben. In manchen Fällen enthalten Cookies Benutzereinstellungen, in ande-ren übermitteln sie Authentifizierungsinformationen. Auf diese Weise brauchen die Benutzer aufWebsites mit Benutzeranmeldung nicht jedes Mal von Neuem ihre Anmeldedaten einzugeben.ASP.NET verwendet Cookies, um die auf Webservern gespeicherten Sitzungen den wiederkehrendenBenutzern zuzuordnen. Dieses Verfahren wird im nächsten Kapitel behandelt. Cookies werden inASP.NET aber auch verwendet, um Benutzer zu identifizieren, die mit Hilfe der formularbasiertenAuthentifizierung validiert wurden. (In � Kapitel 10 gehen wir näher auf die formularbasierteAuthentifizierung ein.) Im Folgenden sehen Sie ein Cookie, das anzeigt, dass der Besucher einer per-sonalisierten Homepage die neuesten Börsenkurse von Amazon, Intel und Microsoft sehen möchte:

Cookie: Stocks=AMZN&INTC&MSFT

Wenn eine Anforderung mit einem Cookie auf einem Server eintrifft, muss dieser das Cookie parsenund interpretieren. Cookies sind höchst anwendungsspezifisch. Ihre Verwendung und Ihre Inhaltekönnen sehr unterschiedlich sein, je nachdem, welche Anwendung sie benutzt.

642.book Page 307 Monday, July 1, 2002 4:37 PM

Page 22: Benutzersteuerelemente - bücher.de · 2012-09-28 · Benutzersteuerelemente 291 Zum Testen des Login-Steuerelements benötigen Sie ein Webformular, zum Beispiel LoginPage1.aspx,

Kapitel 7308

In den meisten Browsern können Cookies deaktiviert werden. Einige Websites weisen deshalb daraufhin, dass Ihnen ohne Cookies nicht alle Funktionen zur Verfügung stehen. Das liegt gewöhnlichdaran, dass diese Seiten Cookies für Round-Trips von Benutzereinstellungen, Anmeldeinformationenund Ähnliches verwenden. Cookies haben durch die Medien einen schlechten Ruf bekommen, dochim Grunde sind sie harmlos und sind sogar ziemlich nützlich, da Benutzer zustandslose Wesen sind,die zur Datenübermittlung vorwiegend ein zustandsloses Protokoll verwenden.

Wie werden Cookies erstellt, und woher weiß ein Browser, wann und wie er ein Cookie versendensoll? Ein Webserver erstellt ein Cookie, indem er es im Header Set-Cookie einer HTTP-Antwortzurückgibt. Mit der folgenden Antwort wird ein Cookie an den anfordernden Browser zurückgege-ben:

HTTP/1.1 200 OKServer: Microsoft-IIS/5.0Date: Wed, 24 Oct 2001 14:12:37 GMTContent-Type: text/htmlContent-Length: 46 . . .Set-Cookie: FavoriteColor=Blue; path=/

Die Komponente Path im Header Set-Cookie teilt dem anfragenden Browser mit, auf welche URL-Untergruppe dieser Domäne sich das Cookie bezieht. Das Attribut path=/ zeigt an, dass das Cookiein jeder Anforderung an diese Domäne übermittelt werden soll. Standardmäßig handelt es sich bei isdomain um die Domäne, an die die Anforderung ursprünglich gerichtet war. Cookies können jedochauch optionale Domain-Attribute für andere Domänen enthalten.

Bei dem folgenden vom Webserver zurückgegebenen Set-Cookie-Header wird das Cookie Favorite-Color in nachfolgenden Anforderungen immer an www.intellect.com gesendet, gleichgültig, in wel-cher Domäne es erstellt wurde:

Set-Cookie: FavoriteColor=Blue; domain=www.wintellect.com/; path=/

Browser brauchen die Cookies im Header Set-Cookie nicht zu beachten, doch die meisten berück-sichtigen sie, wenn die Cookie-Funktion aktiviert ist. Sie speichern die Cookies im Cache, um sie beinachfolgenden Anforderungen wieder an den Server senden zu können.

Die Art der Zwischenspeicherung im Browser hängt vom Typ des Cookies ab. Session-Cookies sindnur gültig, bis die Browseranwendung beendet wird. Sie werden gewöhnlich im Speicher abgelegt.Die Lebensdauer persistenter Cookies kann individuell festgelegt werden und ist unabhängig von derDauer der Browsersitzung. Sie werden auf der Festplatte des Clients gespeichert. (Wenn Sie InternetExplorer verwenden, finden sie die auf Ihrer Festplatte abgelegten Cookies im Ordner Dokumenteund Einstellungen\BenutzerName\Cookies.) Persisitente Cookies unterscheiden sich von Session-Cookies durch das Attribut Expires. Es teilt dem Browser mit, wann das Cookie verfällt. Der folgendeAntwort-Header erstellt ein persistentes Cookie, das am 31. Dezember 2009 um zwölf Uhr mittagsungültig wird:

Set-Cookie: FavoriteColor=Blue; expires=Thu, 31-Dec-2009 12:00:00 GMT; path=/

Cookies ohne Expires-Attribut sind Session-Cookies, alle anderen persistente. Cookies könnenaußerdem Secure-Attribute enthalten, die Browser daran hindern, sie über unverschlüsselte Verbin-

642.book Page 308 Monday, July 1, 2002 4:37 PM

Page 23: Benutzersteuerelemente - bücher.de · 2012-09-28 · Benutzersteuerelemente 291 Zum Testen des Login-Steuerelements benötigen Sie ein Webformular, zum Beispiel LoginPage1.aspx,

Benutzersteuerelemente 309

dungen (ohne HTTPS) zu übermitteln. Das Secure-Attribut ist sinnvoll, wenn Sie Cookies zur Über-mittlung vertraulicher Informationen verwenden, die nicht in falsche Hände geraten dürfen.

Cookies in ASP.NETDie .NET Framework-Klassenbibliothek erleichtert die Verwendung von Cookies durch eine Wrap-perklasse namens HttpCookie (ein Member des Namespaces System.Web). Mit Hilfe einer einfachenAnweisung können Sie ein Cookie erstellen und ihm einen Namen und einen Wert zuweisen:

HttpCookie cookie = new HttpCookie ("FavoriteColor", "Blue");

Die öffentlichen Eigenschaften Domain, Path, Expires und Secure von HttpCookie umschließen diegleichnamigen Cookieattribute. Die folgende Anweisung legt fest, dass das Cookie heute in einerWoche verfallen soll:

cookie.Expires = DateTime.Now + new TimeSpan (7, 0, 0, 0);

Mit den folgenden Anweisungen wird dem Cookie ein absolutes Ablaufdatum (im Gegensatz zueinem relativen) sowie ein Tag mit einem Secure-Attribut zugewiesen:

cookie.Expires = new DateTime (2000, 12, 31); // 31. Dezember 2009cookie.Secure = true

Um den Namen oder den Wert eines Cookies nach seiner Erstellung zu ändern, können Sie dieEigenschaften Name und Value verwenden.

Mit Hilfe von HttpCookie wird die Cookie-Erstellung sehr vereinfacht. Sie können ein mit Http-Cookie angelegtes Cookie auch leicht im Set-Cookie-Header an den Browser zurückgeben. Dazumüssen Sie es einfach der Cookies-Auflistung des Response-Objekts hinzufügen. Mit der folgendenAnweisung wird ein Session-Cookie namens FavoriteColor erstellt und in die HTTP-Antwort einge-fügt. (Beachten Sie, dass es kein Ablaufdatum bekommt. Dadurch wird es zu einem Session-Cookie.)

HttpCookie cookie = new HttpCookie ("FavoriteColor", "Blue");Response.Cookies.Add (cookie);

Das war schon alles! Durch das Hinzufügen des Cookies in die Cookies-Auflistung des Response-Objekts wird sichergestellt, dass es in der HTTP-Antwort zurückgegeben wird. Sie können beliebigviele Cookies hinzufügen, die alle in der Antwort eingefügt werden.

Cookies sind natürlich nur dann sinnvoll, wenn sie auch aus den übermittelten Anforderungen he-rausgelesen werden können. Zu diesem Zweck enthält das Response-Objekt von ASP.NET eineeigene Cookies-Auflistung, die anzeigt, ob und welche Cookies in einer HTTP-Anforderung übermit-telt werden. Der folgende Code liest ein Cookie (über seinen Namen) aus der Anforderung. Er über-prüft, ob sich darin tatsächlich ein Cookie befindet und extrahiert dessen Wert:

HttpCookie cookie = Request.Cookies["FavoriteColor"];if (cookie != null) { string FavoriteColor = cookie.Value; . . .}

642.book Page 309 Monday, July 1, 2002 4:37 PM

Page 24: Benutzersteuerelemente - bücher.de · 2012-09-28 · Benutzersteuerelemente 291 Zum Testen des Login-Steuerelements benötigen Sie ein Webformular, zum Beispiel LoginPage1.aspx,

Kapitel 7310

Die Cookies-Eigenschaft des Request-Objekts ist vom Typ HttpCookieCollection. Wenn Sie wollen,können Sie HttpCookieCollection-Eigenschaften wie Keys, AllKeys oder Count verwenden, um dieCookies in einer HTTP-Anfrage zu enumerieren.

Cookies werden vom Benutzer oder vom Webbrowser gelöscht. Session-Cookies löscht der Benutzereinfach durch das Beenden des Browserprogramms. Persistente Cookies kann man entfernen, indemman die Dateien löscht, in denen sie gespeichert sind. Das erfolgt gewöhnlich über einen Browserbe-fehl (zum Beispiel Cookies löschen in Internet Explorer). Sie können dies jedoch auch manuell odermit Hilfsprogrammen anderer Hersteller tun. Auf Webservern werden Cookies auf folgende Weisegelöscht:

b Durch die Rückgabe eines Set-Cookie-Headers, in dem die Namen der zu löschenden Cookies mitNullwerten enthalten sind

b Durch das Einfügen eines bereits abgelaufenen Datums in diesen Set-Cookie-Headern

Der folgende Set-Cookie-Header weist den Browser an, das Cookie FavoriteColor zu löschen. DieseMethode funktioniert unabhängig davon, ob es sich bei FavoriteColor um ein Session- oder um einpersistentes Cookie handelt:

Set-Cookie: FavoriteColor=; expires=Wed, 30-Sep-1959 07:15:00 GMT

In einer ASP.NET-Anwendung können Sie das Cookie FavoriteColor auf folgende Weise löschen:

HttpCookie cookie = new HttpCookie ("FavoriteColor");cookie.Expires = new DateTime (1959, 9, 30);Response.Cookies.Add (cookie);

Wenn nur ein einziger Wert an den Konstruktor von HttpCookie übergeben wird, erhält das Cookieeinen Name, bekommt jedoch keinen Wert zugewiesen. Daraus ergibt sich ein ähnlicher Set-Cookie-Header wie der hier gezeigte.

Mehrwertige Cookies

Häufig enthalten Cookies mehrere Name/Wert-Paare. Im folgenden Cookie-Header wird zum Bei-spiel ein Cookie übermittelt, das einen Benutzernamen und ein Kennwort enthält:

Cookie: AuthInfo=UserName=Jeffpro&Password=imbatman

Das ist problemlos möglich, da das Cookie technisch gesehen nach wie vor nur einen einzigen Wertbesitzt, nämlich UserName=Jeffpro&Password=imbatman. Die Anwendung auf dem Server kanndiesen Wert lesen, parsen und die Unterelemente extrahieren.

Zur Erleichterung des Umgang mit mehrwertigen Cookies (und um das manuelle Parsen der Unter-elemente zu umgehen) weist HttpCookies die Eigenschaften HasKeys und Values auf. HasKeys istein boolescher Wert, der angibt, ob der Wert des Cookies Unterelemente enthält. Values ist eine Auf-listung, die die Unterelemente anzeigt. Mit den folgenden Anweisungen wird ein Cookie mit zweiUnterelementen erstellt und zurückgegeben:

HttpCookie cookie = new HttpCookie ("AuthInfo");cookie.Values["UserName"] = "Jeffpro";cookie.Values["Password"] = "imbatman";Response.Cookies.Add (cookie);

642.book Page 310 Monday, July 1, 2002 4:37 PM

Page 25: Benutzersteuerelemente - bücher.de · 2012-09-28 · Benutzersteuerelemente 291 Zum Testen des Login-Steuerelements benötigen Sie ein Webformular, zum Beispiel LoginPage1.aspx,

Benutzersteuerelemente 311

Der folgende Code ruft den im Cookie gekapselten Benutzernamen und das Kennwort aus der HTTP-Anforderung ab:

HttpCookie cookie = new HttpCookie ("AuthInfo");if (cookie != null) { string UserName = cookie.Values["UserName"]; string Password = cookie.Values["Password"];}

Sie können die in der Eigenschaft Value enthaltenen Unterelemente auch mit Hilfe von Membern derKlasse NameValueCollection enumerieren. (Values ist vom Typ NameValueCollection.) Eine Enu-merierung ist dann sinnvoll, wenn Sie die Namen der Unterelemente nicht von vornherein kennen.

Die Seite MyQuotesDie Anwendungen in Abbildung 7.4 und Listing 7.12 zeigen, wie Sie dynamisch geladene Benutzer-steuerelemente und Cookies zur Erstellung personalisierter Webseiten kombinieren können. Wenndie Datei MyQuotes.aspx das erste Mal dargestellt wird, enthält sie lediglich ein Kontrollkästchenmit dem Text Show quotes. Durch Aktivieren des Kästchens wird das in MyQuotes.ascx definierteBenutzersteuerelement dynamisch geladen und der Seite hinzugefügt. Aus dem Internet holt sichMyQuotes.ascx dann die neusten Börsenkurse von Amazon, Intel und Microsoft und stellt diese ineinem DataGrid dar. Bei jeder Seitenaktualisierung werden auch die Kurse aktualisiert.

Wenn man das Kontrollkästchen markiert, wird nicht nur MyQuotes.ascx geladen, sondern auch einCookie namens MyQuotes erstellt und an den anfordernden Browser zurückgegeben. Dabei handeltes sich um ein persistentes Cookie mit einer Gültigkeitsdauer von einem Jahr. Bei jedem Laden derSeite sucht der Page_Load-Handler das MyQuotes-Cookie und lädt daraufhin das Benutzersteuer-element. Wenn Sie das Kästchen aktivieren, den Browser schließen und wieder öffnen, ist das Benut-zersteuerelement beim nächsten Aufruf von MyQuotes.aspx daher immer noch da. Sollten Sie dasKästchen deaktivieren, wird das Cookie gelöscht und das Steuerelement beim nächsten Mal nichtwieder geladen.

Abbildung 7.7: Die Seite MyQuotes

642.book Page 311 Monday, July 1, 2002 4:37 PM

Page 26: Benutzersteuerelemente - bücher.de · 2012-09-28 · Benutzersteuerelemente 291 Zum Testen des Login-Steuerelements benötigen Sie ein Webformular, zum Beispiel LoginPage1.aspx,

Kapitel 7312

Die dargestellten Börsenkurse sind tatsächlich aktuell, wenn auch mit 20 Minuten Verzögerung.Diese (annähernd) in Echtzeit abgerufenen Kurse holt sich MyQuotes mit Hilfe eines Webdienstes.In unserem Fall handelt es sich dabei um den Dienst Delayed Stock Quote, der von XMethodsunterhalten wird (www.xmethods.com). Webdienste wurden in diesem Buch bisher noch nicht for-mell eingeführt, Sie erfahren jedoch in � Kapitel 11 alles darüber. Ich habe sie verwendet, um dasBeispiel ein wenig interessanter zu gestalten. Der Nachteil bei der Verwendung eines Webdienstesbesteht darin, dass Sie keine Garantie haben, ob er morgen immer noch existiert. MyQuotes funktio-nierte sehr gut, als ich die Datei erstellt habe. Es könnte jedoch sein, dass der Dienst Delayed StockQuote nicht mehr verfügbar ist, wenn Sie dieses Buch lesen. Möglicherweise hat sich auch sein URLoder seine Programmierschnittstelle geändert. In diesem Fall wäre MyQuotes ein eher langweiligesBeispiel.

Um MyQuotes ausführen zu können, müssen Sie die mitgelieferte DLL (MyQuotes.dll) in das Ver-zeichnis bin im Anwendungsstamm kopieren. Wenn sich MyQuotes.aspx und MyQuotes.ascx imVerzeichnis wwwroot befinden, legen Sie die DLL unter wwwroot\bin ab. MyQuotes.dll enthält eineWebdienst-Proxyklasse namens netxmethodsservicesstockquoteStockQuoteService, mit deren Hilfedas Benutzersteuerelement mit dem Dienst Delayed Stock Quote kommuniziert. Es verwendet dafürSOAP-Nachrichten (Simple Object Access Protocol), die über HTTP übertragen werden. Dank dieserProxyklasse können die Börsenkurse mit dem folgenden einfachen Code abgerufen werden (wobeider Code für die Ausnahmebehandlung zur Vereinfachung weggelassen wurde):

netxmethodsservicesstockquoteStockQuoteService qs = new netxmethodsservicesstockquoteStockQuoteService ();

decimal amzn;decimal intc;decimal msft;

amzn = (decimal) qs.getQuote ("AMZN");intc = (decimal) qs.getQuote ("INTC");msft = (decimal) qs.getQuote ("MSFT");

MyQuotes.dll wurde aus der Quellcodedatei MyQuotes.cs erstellt, die ihrerseits aus Wsdl.exeerzeugt wurde. Seien Sie unbesorgt, falls Sie dies im Moment noch nicht ganz verstehen. Die Einzel-heiten hierzu werden in � Kapitel 11 erläutert. Viele Menschen sind der Meinung, dass Webdienstedie Zukunft des Internets sind. Ich hoffe daher, dass Sie dieses kleine Beispiel neugierig daraufgemacht hat.

MyQuotes.aspx

<%@ Register TagPrefix="user" TagName="MyQuotes" Src="MyQuotes.ascx" %>

<html> <body> <h1>MyQuotes</h1> <hr> <form runat="server"> <asp:CheckBox ID="ShowQuotes" Text="Show quotes" RunAt="server" AutoPostBack="true" OnCheckedChanged="OnCheckBoxClicked" /> <span ID="PlaceHolder" runat="server" /> </form> </body>

642.book Page 312 Monday, July 1, 2002 4:37 PM

Page 27: Benutzersteuerelemente - bücher.de · 2012-09-28 · Benutzersteuerelemente 291 Zum Testen des Login-Steuerelements benötigen Sie ein Webformular, zum Beispiel LoginPage1.aspx,

Benutzersteuerelemente 313

</html>

<script language="C#" runat="server"> const string CookieName = "MyQuotes"; const string CookieVal = "ShowQuotes";

void Page_Load (Object sender, EventArgs e) { if (!IsPostBack) { // Falls ein Cookie namens "MyQuotes" vorhanden ist, wird das // Benutzersteuerelement geladen und das Kontrollkästchen "Show quotes" aktiviert HttpCookie cookie = Request.Cookies["MyQuotes"]; if (cookie != null) { MyQuotes_ascx ctrl = (MyQuotes_ascx) LoadControl ("MyQuotes.ascx"); ctrl.Width = Unit.Percentage (100); PlaceHolder.Controls.Add (ctrl); ShowQuotes.Checked = true; } } }

void OnCheckBoxClicked (Object sender, EventArgs e) { if (ShowQuotes.Checked) { // Lädt das Benutzersteuerelement MyQuotes_ascx ctrl = (MyQuotes_ascx) LoadControl ("MyQuotes.ascx"); ctrl.Width = Unit.Percentage (100); PlaceHolder.Controls.Add (ctrl);

// Gibt ein Cookie zurück, das ein Jahr Gültigkeit hat HttpCookie cookie = new HttpCookie (CookieName, CookieVal); cookie.Expires = DateTime.Now + new TimeSpan (365, 0, 0, 0); Response.Cookies.Add (cookie); } else { // Löscht das Cookie "MyQuotes" HttpCookie cookie = new HttpCookie (CookieName); cookie.Expires = new DateTime (1959, 9, 30); Response.Cookies.Add (cookie); } }</script>

MyQuotes.ascx

<%@ Import Namespace="System.Data" %><%@ Import Namespace="System.Drawing" %>

<asp:DataGrid ID="MyGrid" RunAt="server" BorderWidth="1" BorderColor="lightgray" CellPadding="2" Font-Name="Verdana" Font-Size="8pt" GridLines="vertical"> <HeaderStyle BackColor="maroon" ForeColor="white" HorizontalAlign="center" /> <ItemStyle BackColor="white" ForeColor="black" />

642.book Page 313 Monday, July 1, 2002 4:37 PM

Page 28: Benutzersteuerelemente - bücher.de · 2012-09-28 · Benutzersteuerelemente 291 Zum Testen des Login-Steuerelements benötigen Sie ein Webformular, zum Beispiel LoginPage1.aspx,

Kapitel 7314

<AlternatingItemStyle BackColor="beige" ForeColor="black" /></asp:DataGrid><span style="font-family: verdana; font-size: 8pt"> Quotes are delayed by 20 minutes</span>

<script language="C#" runat="server"> Unit MyWidth;

public Unit Width { get { return MyWidth; } set { MyWidth = value; } }

void Page_Load (Object sender, EventArgs e) { if (MyWidth != Unit.Empty) MyGrid.Width = MyWidth;

// Holt die Börsenkurse für AMZN, INTC und MSFT netxmethodsservicesstockquoteStockQuoteService qs = new netxmethodsservicesstockquoteStockQuoteService ();

decimal amzn; decimal intc; decimal msft;

try { amzn = (decimal) qs.getQuote ("AMZN"); } catch { amzn = -1.0m; }

try { intc = (decimal) qs.getQuote ("INTC"); } catch { intc = -1.0m; }

try { msft = (decimal) qs.getQuote ("MSFT"); } catch { msft = -1.0m; }

// Fügt die Kurse einem DataSet hinzu DataSet ds = new DataSet (); DataTable dt = new DataTable ("Quotes"); ds.Tables.Add (dt);

DataColumn col1 = new DataColumn ("Symbol", typeof (string)); DataColumn col2 = new DataColumn ("Price", typeof (string));

642.book Page 314 Monday, July 1, 2002 4:37 PM

Page 29: Benutzersteuerelemente - bücher.de · 2012-09-28 · Benutzersteuerelemente 291 Zum Testen des Login-Steuerelements benötigen Sie ein Webformular, zum Beispiel LoginPage1.aspx,

Benutzersteuerelemente 315

dt.Columns.Add (col1); dt.Columns.Add (col2);

DataRow row = dt.NewRow (); row["Symbol"] = "AMZN"; row["Price"] = (amzn == -1.0m) ? "Unavailable" : String.Format ("{0:c}", amzn); dt.Rows.Add (row);

row = dt.NewRow (); row["Symbol"] = "INTC"; row["Price"] = (intc == -1.0m) ? "Unavailable" : String.Format ("{0:c}", intc); dt.Rows.Add (row);

row = dt.NewRow (); row["Symbol"] = "MSFT"; row["Price"] = (msft == -1.0m) ? "Unavailable" : String.Format ("{0:c}", msft); dt.Rows.Add (row);

// Verbindet das DataGrid mit dem DataSet MyGrid.DataSource = ds; MyGrid.DataBind (); }</script>

Listing 7.9: Der Quellcode von MyQuotes

Fragmentcaching In � Kapitel 5 haben wir das Thema Ausgabecaching bereits kurz gestreift. Dort wurde beschrieben,wie Sie durch das Einfügen von @ OutputCache-Direktiven in Ihre ASPX-Dateien die Leistung vonWebformularen verbessern können. Durch die folgende Anweisung in einer ASPX-Datei wirdASP.NET beispielsweise aufgefordert, die Seite einmal zu erstellen und eine Kopie davon 60 Sekun-den lang im Ausgabecache zu speichern:

<%@ OutputCache Duration="60" VaryByParam="None" %>

Wenn vor Ablauf dieser Minute weitere Anforderungen für die Seite eingehen, kann ASP.NET dasgespeicherte HTML ausgeben. Durch Caching lässt sich die Leistung einer Anwendung steigern, dadie Seiten zur Darstellung nicht immer wieder neu ausgeführt werden müssen.

Ein Nachteil bei der Verwendung von @ OutputCache-Direktiven in ASPX-Dateien besteht darin,dass man nicht gezielt einzelne Informationen zwischenspeichern kann, sondern immer nur diegesamte Seite. Benutzersteuerelemente bieten eine Lösung für dieses Problem, da mit ihrer Hilfe ein-zelne Teile einer Seite im Cache abgelegt werden können, während andere Bereiche dynamischerstellt werden. Diese Art der Zwischenspeicherung wird als Subpage- oder Fragmentcachingbezeichnet. Dank dieser Technik können Sie die Leistung Ihrer Anwendungen verbessern, da Sie dasAusgabecaching von ASP.NET dadurch für Seiten verwenden können, die statische und dynamischeInhalte kombinieren.

642.book Page 315 Monday, July 1, 2002 4:37 PM

Page 30: Benutzersteuerelemente - bücher.de · 2012-09-28 · Benutzersteuerelemente 291 Zum Testen des Login-Steuerelements benötigen Sie ein Webformular, zum Beispiel LoginPage1.aspx,

Kapitel 7316

Beim Fragmentcaching wird die Seite zunächst in unterschiedliche Bereiche eingeteilt: in statischeInhalte (Inhalte, die sich nicht bei jeder Anforderung ändern und daher zwischengespeichert werdenkönnen) und dynamische Inhalte (veränderliche Inhalte, die nicht gespeichert werden sollten).Danach werden die statischen Bereiche der Seite als Benutzersteuerelemente implementiert und @Output Cache-Direktiven zur Unterstützung des Ausgabecachings in deren ASCX-Dateien eingefügt.Die Zwischenspeicherung erfolgt also nur für den Inhalt, der von den ASCX-Dateien erstellt wird,nicht für andere Seiteninhalte. Sie können in die @ Output Cache-Direktiven auch VaryByControl-Attribute einfügen. Auf diese Weise können Sie aufgrund ihrer jeweiligen Eigenschaftswerte unter-schiedliche Instanzen desselben Steuerelements zwischenspeichern.

Dies lässt sich am besten an einem Beispiel verdeutlichen. Vielleicht ist Ihnen bereits aufgefallen,dass die weiter vorne in diesem Kapitel vorgestellte Anwendung MyQuotes sehr langsam läuft. Beijeder Aktivierung des Kontrollkästchens Show Quotes ruft das Steuerelement die Börsenkurse voneinem Webdienst ab. Sie können die Leistung ein wenig erhöhen, indem Sie eine @ Output Cache-Direktive in die Datei MyQuotes.aspx einfügen. Wenn die Seite jedoch noch andere Steuerelementeenthält (was in der Praxis der Fall wäre), würde auch deren Ausgabe zwischengespeichert. Eine bes-sere Lösung besteht darin, die folgende Direktive zu MyQuotes.ascx hinzuzufügen:

<%@ OutputCache Duration="60" VaryByParam="None" %>

Nun wird lediglich das Raster mit den Börsenkursen gespeichert, der übrige Inhalt der Seite aberdynamisch erstellt. Die Börsenkurse werden jetzt zwar mit bis zu 60 Sekunden Verzögerung darge-stellt, doch da sie sowieso mit 20 Minuten Verspätung eintreffen, macht dies nicht viel aus. Dank die-ser Methode kann Ihr Webserver nun pro Sekunde bis zu tausend Anforderungen mehr verarbeiten.

Dieses Beispiel ist zugegebenermaßen sehr vereinfacht, da es sich bei MyQuotes um ein so simplesSteuerelement handelt. Es sieht auf jeder Webseite gleich aus. Das Steuerelement XmlNavBar ausdiesem Kapitel ist da schon etwa realistischer. Wenn XmlNavBar einmal initialisiert ist, verändertsich seine HTML-Ausgabe so lange nicht mehr, bis seine Eigenschaften dynamisch geändert werden.Das bedeutet, dass es sich hervorragend für das Ausgabecaching eignet. Wenn Sie allerdings mehrereXmlNavBar-Steuerelemente auf Ihrer Seite verwenden und jedes von ihnen anders konfigurieren,müssen auch verschiedene Versionen des Steuerelements zwischengespeichert werden.

Zu diesem Zweck gibt es das Attribut VaryByControl. Sie können ASP.NET damit anweisen, fürjeden Eigenschaftswert eines Benutzersteuerelements eine andere Version zu speichern. Beispiels-weise können Sie zwei verschiedene XmlNavBar-Steuerelemente verwenden, die mit unterschiedli-chen XML-Dateien initialisiert werden, und dann für jede XML-Datei eine andere Version zwischen-speichern, indem Sie die Eigenschaft XmlSrc in einem VaryByControl-Attribut aufführen:

<%@ OutputCache Duration="3600" VaryByParam="None" VaryByControl="XmlSrc %>

Wenn Sie XmlNavBar-Steuerlemente durch die Änderung mehrerer Eigenschaften anpassen, kön-nen Sie die Namen dieser einzelnen Eigenschaften in der @ OutputCache-Direktive durch Semikolatrennen:

<%@ OutputCache Duration="3600" VaryByParam="None" VaryByControl="XmlSrc;ForeColor;MouseOverColor" %>

Das Steuerelement wird nun innerhalb einer Stunde nur noch ein Mal physisch ausgeführt, gleichgül-tig, wie viele Seiten XmlNavBar-Steuerelemente enthalten oder wie oft diese angefordert werden.Das hat den Vorteil, dass sich auch der Verarbeitungsaufwand auf Ihrem Server entsprechend verrin-gert.

642.book Page 316 Monday, July 1, 2002 4:37 PM

Page 31: Benutzersteuerelemente - bücher.de · 2012-09-28 · Benutzersteuerelemente 291 Zum Testen des Login-Steuerelements benötigen Sie ein Webformular, zum Beispiel LoginPage1.aspx,

Benutzersteuerelemente 317

Das Ausgabecaching erfolgt in ASP.NET anwendungsgebunden. Daher brauchen Sie sich nicht umVaryControl-Attribute zu kümmern, wenn Sie unterschiedliche Navigationsleisten in verschiedenenAnwendungen einsetzen. ASP.NET speichert dann automatisch zwei Versionen im Cache.

Vorschau: Benutzerdefinierte SteuerelementeMit Benutzersteuerelementen lässt sich eine komplexe Darstellungs- und Verhaltenslogik in wieder-verwendbaren Komponenten speichern, die Entwickler auch untereinander austauschen können. DaASCX beim Ausgabecaching von ASP.NET berücksichtigt wird, spielen Benutzersteuerelemente aucheine wichtige Rolle bei der Leistungsverbesserung von Anwendungen.

Als ich das erste Mal über Benutzersteuerelementen las, war mir nicht sofort klar, welches Potenzialin ihnen steckt. »Ganz nett«, dachte ich mir, »vielleicht finde ich ja irgendwann Verwendung dafür.«Seitdem habe ich allerdings mehr Verwendungszwecke gefunden, als ich mir je hätte träumen lassen.Ich glaube in der Tat, dass Benutzersteuerelemente zu den drei oder vier wichtigsten Funktionen vonASP.NET zählen, und sei es nur aufgrund der Tatsache, dass sie die Leistung von Webanwendungenverbessern, weil dadurch bestimmte Bereiche einer Seite im Cache gespeichert und andere bei jederAnfrage neu erstellt werden können.

Websteuerelemente stehen auf meiner Liste der nützlichen Funktionen ebenfalls weit oben. Nichtwegen der in der .NET Framework-Klassenbibliothek enthaltenen vorgefertigten Steuerelemente,sondern weil Entwickler zusätzlich zu diesen ihre eigenen benutzerdefinierten Steuerelementeschreiben können. Benutzerdefinierte Steuerelemente erweitern die Möglichkeiten normaler Steuer-elemente und den Funktionsumfang von ASP.NET ganz ungemein. Im Folgenden werden Sie dafüreinige überzeugende Beispiele sehen.

642.book Page 317 Monday, July 1, 2002 4:37 PM

Page 32: Benutzersteuerelemente - bücher.de · 2012-09-28 · Benutzersteuerelemente 291 Zum Testen des Login-Steuerelements benötigen Sie ein Webformular, zum Beispiel LoginPage1.aspx,

642.book Page 318 Monday, July 1, 2002 4:37 PM