Dieser Artikel ist ein Auszug aus dem Buch ".NET 3.0 Crashkurs" und beschäftigt sich mit den AJAX-Erweiterungen
für die Webprogrammierung mit ASP.NET 2.0. Diese Erweiterungen sind nicht
zusammen mit ASP.NET 2.0 im November 2005 erschienen und auch nicht zusammen
mit .NET 3.0 im November 2006, sondern im Januar 2007 als eine kostenlos
Erweiterung.
HINWEIS
ASP.NET AJAX ist eine
weitaus mächtigere Lösung als die in ASP.NET 2.0 enthaltenen Client-Rückrufe,
die immer nur eine Ein- und eine Ausgabezeichenkette zuließen.
Das Hype-Wort »Web 2.0« ist in aller Munde. Unter der
technischen Seite von Web 2.0 verstehen viele eine neue Generation von
Webanwendungen, bei denen mehr clientseitiger JavaScript-Code eingesetzt wird,
um mit Webservern zu kommunizieren. Web 2.0 umfasst u. a. folgende Szenarien:
§
Austausch von Seitenteilen anstelle des ständigen Neuladens von
kompletten Webseiten
§
Kopplung von verschiedenen serverseitigen Webanwendungen (sogenannte
Mashups)
Basis für diese Web 2.0-Szenarien ist die Technologie
Asynchronous JavaScript and XML (AJAX), die abseits der üblichen HTTP-Rundgänge
(Roundtrips) Aufrufe des Webservers vom Browser ermöglicht. In den Aufrufen
werden XML-Daten ausgetauscht, wobei die XML-Daten auf der Clientseite per
JavaScript verpackt und über HTTP versendet werden. Die Aufrufe heißen daher
auch XML-HTTP-Requests. Die XML-Antwort des Servers erhält der Client in der
HTTP-Antwort. Durch die asynchrone Ausführung wird der Browser in der
Zwischenzeit nicht blockiert. Eine komplementäre Technologie für AJAX ist das
Document Object Model (DOM), das die dynamische Veränderung von im Browser
dargestellten Seiten ermöglicht.
HINWEIS
Wirklich neu an AJAX ist
nur der Name, der erstmals im Februar 2005 von Jesse James Garrett in [JJG05]
verwendet wurde. Die Idee des entfernten Prozeduraufrufs aus dem Browser heraus
wurde erstmals schon im Jahr 1998 von Microsoft im Internet Explorer 4.0 in
Form des MicrosoftRemote Scripting
(MSRS)
verwendet. MSRS basierte auf einem Java Applet. Im Internet Explorer 5.0 ist
später das
XmlHttpRequest-Objekt erschienen, das noch
heute in dieser Form im Internet Explorer und anderen Browsern existiert und
jetzt den Kern von AJAX bildet.
Im Internet Explorer bis Version 6.0 ist XML-HTTP durch
ein COM-Objekt (Microsoft.XmlHttp
) realisiert, in Mozilla (Netspace, Firefox, Safari etc.) sowie im
Internet Explorer 7.0 durch das eingebaute Objekt
XmlHttpRequest
. Neu ist, dass es sogenannte AJAX-Frameworks gibt, die die Handhabung
dieses Objekts stark vereinfachen und eine Abstraktion bieten, sodass aus
JavaScript heraus Funktionen eines Proxy aufgerufen werden, die auf dem Server
als Funktionsaufrufe signalisiert werden.
ACHTUNG
Aufgrund der Tatsache, dass
die XML-HTTP-Unterstützung im Internet Explorer bis Version 6.0 ein COM-Objekt
ist, kann AJAX dort nur funktionieren, wenn in den Sicherheitseinstellungen des
Internet Explorers für die jeweilige Zone »Script ActiveX controls marked safe
for scripting« aktiviert ist. Das
XmlHttpRequest
-Objekt liegt inzwischen dem W3C zur Standardisierung vor [W3C05].

Abbildung 21.1 AJAX im Vergleich zum klassischen Rundgangmodell
WICHTIG
AJAX bedeutet auch neue
Schwierigkeiten und Herausforderungen, insbesondere
§
in Hinblick auf Benutzer, die JavaScript deaktiviert haben
§
die »Zurück«-Funktion der Browser, die AJAX-Aufrufe nicht
berücksichtigt, und
§
die Zugänglichkeit für Menschen mit körperlichen Einschränkungen.
Für eine detaillierte
Diskussion von AJAX-Grundlagen sei hier auf [MiLe01] verwiesen.
Microsoft-AJAX
Produkte
Microsofts Beitrag zum AJAX-Hype wurde ursprünglich auf der
Professional Developer Conference (PDC) im September 2005 in Los Angeles
angekündigt unter dem Codenamen »Atlas«. Das Erscheinen war für Ende 2007 im
Rahmen von »Orcas« geplant. Aufgrund des Kundendrucks hat Microsoft dann aber
einen Teil vorab veröffentlicht.
Die AJAX-Produktgruppe besteht daher aus folgenden Teilen:
§
Die
Microsoft AJAX Library
ist eine JavaScript-Bibliothek, die AJAX-Funktionen und
JavaScript-Erweiterungen bereitstellt. Die Microsoft AJAX Library ist
browserunabhängig (durch Abstraktion von der Implementierung des
XmlHttpRequest
-Objekts) und zudem unabhängig von der eingesetzten Servertechnologie.
Microsoft liefert mit der ersten Version der AJAX Library eine Abstraktion für
die Browser Internet Explorer, Firefox, Safari und Opera.
§
Die
ASP.NET-AJAX-Erweiterungen
(ASPAJAXExtSetup.msi) umfassen serverseitige
Unterstützung für AJAX-Entwicklung und sind eine gute Ergänzung zu der
Microsoft AJAX Library. Die beiden
wesentlichen Konzepte in den ASP.NET-AJAX-Erweiterungen sind hier die partielle
Seitenerzeugung und die asynchronen Browser-Rückrufe an den Server.
§
Das optionale
AJAX Control Toolkit
geht über AJAX im engeren Sinne hinaus und stellt eine Sammlung von
DHTML-Widgets für JavaScript-basierte Zusatzfunktionen im Browser bereit. Dazu
gehören Eingabeprüfung, Navigationselemente und grafische Spielereien wie
Schatten und Animationen.
Für Visual Studio gibt es zwar noch keine
Assistenten, aber zumindest eine Projektvorlage sowie rudimentäre
Unterstützung für den Webform-Designer und das Eigenschaftsfenster.
HINWEIS
Nicht alle Konzepte aus dem
Atlas-Projekt sind im Januar 2007 als endgültiges Produkt erschienen. Microsoft
hat Atlas gespalten in einen Teil, der im Januar 2007 erschienen ist, und in
einen Teil, der mit .NET 3.5 Ende 2007 erscheinen soll. Deshalb gibt es
parallel zu der endgültigen Version von ASP.NET AJAX 1.0 bereits eine
Vorabversion der zweiten Version unter dem Namen »ASP.NET AJAX Futures«.
Installationspakete
und Quellcode
ASP.NET AJAX ist nicht Teil von .NET 3.0, sondern eine
Ergänzung zu .NET 2.0, aber auch lauffähig auf
einem Rechner mit .NET Framework 3.0. Mit .NET 3.5 (Ende 2007) will Microsoft die AJAX-Erweiterungen
in den Kern von ASP.NET integrieren.
Auf dem Download-Server [ASPNET01] von Microsoft kann man
die AJAX Library einzeln oder zusammen mit den ASP.NET-AJAX-Erweiterungen unter
dem Namen ASP.NET AJAX beziehen. Das Control Toolkit gibt es bei dem
Quellcode-Portal CodePlex [CODEPLEX02].
Zu allen drei Produkten hat Microsoft den Quellcode
offengelegt und bietet beim Control Toolkit und der AJAX Library auch an, dass
man den Code in veränderter Form weiterverbreiten darf. Der Quellcode des
serverseitigen Teils ist aber auf den Einsatz beim Debugging beschränkt.
In Hinblick auf den clientseitigen Teil einer AJAX-Lösung
schauen viele Webentwickler sehr argwöhnisch auf die Größe der einzubindenden
JavaScript-Lösung. Die Microsoft AJAX Library umfasst drei
JavaScript-Bibliotheken (MicrosoftAjax.js
,
MicrosoftAjaxTimer.js
und
MicrosoftAjaxWebForms.js
), die zur Laufzeit eine Größe von zusammen 113 KB haben. Zu allen drei
Bibliotheken gibt es aber auch eine »Debug«-Variante mit Quellcodekommentaren,
Quellcodeformatierung und sprechenden Variablennamen. Diese »Debug«-Variante
umfasst zusammen 371 KB. Die ASP.NET-AJAX-Erweiterungen binden die
»Debug«-Skriptdateien nur ein, wenn Debugging für die Webanwendung aktiv ist.
Visual
Studio-Integration
Die Installation der ASP.NET AJAX-Erweiterungen ergänzt
Visual Studio um die Projektvorlage »ASP.NET AJAX Enabled Website«. Die Nutzung
der Projektvorlage ist ratsam, denn für das Funktionieren von ASP.NET AJAX sind
neben einer Referenz auf die Assembly
System.Web.Extensions.dll
auch umfangreiche Konfigurationseinstellungen notwendig, damit sich die
Erweiterungen in die bestehende Infrastruktur integrieren. So muss zum Beispiel
der HTTP-Handler für die Dateinamenerweiterung .asmx
auf die
System.Web.Extensions.dll
umgebogen werden, damit die Webservices auch JSON anstelle von SOAP erzeugen.
Leider gibt es noch keinen Assistenten, um die
Konfigurationseinstellungen nachträglich in eine Konfigurationsdatei einer
bestehenden Webanwendung einzubetten. Hier muss der Webentwickler sorgfältig
per Kopieren&Einfügen die notwendigen Einstellungen aus einem der bei der
Installation mitgelieferten
web.config-Dateien übernehmen – sonst fliegen ihm
zahlreiche Fehlermeldungen um die Ohren.
ScriptManager
Das
ScriptManager
-Serversteuerelement, das Teil der ASP.NET-AJAX-Erweiterungen ist, muss
auf jeder Webseite erscheinen, die AJAX verwenden soll. Es ist ein
Entwurfszeitsteuerelement und wird in dem Designer nur als grauer Kasten (wie
die Datenquellensteuerelemente) dargestellt. Zur Laufzeit sorgt das
ScriptManager
-Serversteuerelement für die Einbindung der in der Seite benötigten
JavaScript-Dateien.
JavaScript-Erweiterungen
Als Teil der Microsoft AJAX Library hat Microsoft die
Sprache JavaScript um Konzepte der Objektorientierung (Klassen, Vererbung,
Namensräume, Schnittstellen) erweitert. Da die Erweiterungen selbst wieder in
JavaScript geschrieben sind, ist weder ein .NET Framework noch ein
ActiveX-Steuerelement notwendig und eine Browserunabhängigkeit möglich.
Ebenfalls enthalten in der AJAX Library sind Erweiterungen eingebauter
JavaScript-Typen wie
Object
,
Array
,
Number
,
String
,
Boolean
und
Error
. Über eine zusätzliche Klassenbibliothek besitzt JavaScript plötzlich
auch die selbstanalytischen Fähigkeiten von Reflection. All dies geschieht mit
dem Ziel, dem .NET-Entwickler den gewohnten Komfort auch in JavaScript zu
bieten.
Partielle
Seitenerzeugung
Die einfachste Nutzung der ASP.NET-AJAX-Lösung stellt die
partielle Seitenerzeugung (Partial Page Rendering) dar. Dabei tauscht der
Browser bei einem Rundgang zum Server nicht die ganze Seite aus, sondern nur
ein oder mehrere Seitenfragmente. Die Seitenfragmente erzeugt der Server im
Fall des Einsatzes von ASP.NET durch Ausführung von Serversteuerelementen, die
HTML erzeugen. Der Webserver erkennt an speziellen Parametern des Aufrufs, dass
nicht die ganze Seite neu zu erzeugen ist, sondern nur einzelne Teile. Der
Aufwand für den Browser ist minimal: JavaScript muss nur den Inhalt einer wohl
definierten Region im Document Object Model (DOM) der Webseite durch das neue
Fragment ersetzen.
UpdatePanel
Programmieraufwand für die partielle Seitenerzeugung
entsteht weder auf dem Client noch auf dem Server: Microsoft hat sowohl das
notwendige JavaScript implementiert als auch die notwendigen Anpassungen von
ASP.NET bereits vorgenommen. Der Webentwickler muss der Webseite nur zwei
Serversteuerelemente hinzufügen: ein
ScriptManager
-Steuerelement, das die notwendigen Client-Skripte in die Seite
einbindet, und ein (oder mehrere)
UpdatePanel
-Steuerelement(e), das die zu aktualisierenden Seitenfragmente
aufspannt. Ein
UpdatePanel
-Steuerelement bietet selbst keine visuelle Darstellung, sondern grenzt
nur statische und dynamische Seitenbereiche voneinander ab. Es kann pro Seite
beliebig viele und auch verschachtelte
UpdatePanel
-Steuerelemente geben.
Aktualisierungseinstellungen
Per Voreinstellung führt ein Klick auf eine Schaltfläche
oder einen Hyperlink in einem
UpdatePanel
-Steuerelement zu einem AJAX-Aufruf des Webservers, bei dem ASP.NET den
UpdatePanel
-Inhalt serverseitig neu erzeugt.
Bei komplexeren Abhängigkeiten zwischen Steuerelementen und
zu aktualisierenden Seitenfragmenten kann auch expliziter Programmcode die
Aktualisierung einzelner Seitenteile anstoßen, indem man serverseitig die
Methode
Update()
auf dem
UpdatePanel
-Steuerelement aufruft. Auch clientseitig kann man Code hinzufügen, der
zu Beginn oder am Ende eines AJAX-Rückrufs ausgeführt wird.
Mit dem Attribut
UpdateMode
im
UpdatePanel
-Steuerelement legt man fest, wann das Seitenfragment aktualisiert wird:
§
UpdateMode="Always"
: Wird immer beim Rückruf aktualisiert. Dies ist die
Standardeinstellung.
§
UpdateMode="Conditional"
: Wird nur fallweise aktualisiert, abhängig vom definierten Trigger
(siehe nächster Abschnitt) oder vom manuellen Aufruf der
Update()
-Methode.
TIPP
Mit
ChildrenAsTriggers =
"false"
legt man fest, dass untergeordnete Steuerelemente bei einem Rückruf nicht
automatisch das Seitenfragment aktualisieren.
Beispiel
Möchte man zum Beispiel erreichen, dass beim Blättern in
einem
GridView
-Steuerelement nicht jedes Mal die ganze umgebende Seite neu geladen
wird, muss der Entwickler nichts anderes tun, als das
GridView
-Steuerelement in das
UpdatePanel
-Steuerelement einzubetten. Fortan kann der Endbenutzer ohne Flackern
und ohne Veränderung der Scroll-Position des Browser-Fensters im Datenbestand
stöbern.
<asp:ScriptManager
ID="SM1" runat="server" AutoPostBack="True">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
Filter nach Abflugort:
<asp:DropDownList ID="C_Ort" runat="server"
…
</asp:DropDownList>
<asp:GridView ID="C_Fluege" runat="server"
…
</asp:GridView>
</ContentTemplate>
…
<asp:DropDownList ID="C_Seitengroesse" runat="server" AutoPostBack="True"
…
</asp:DropDownList>
</asp:UpdatePanel>
Listing
21.1 Einsatz des
UpdatePanel-Steuerelements

|
Abbildung 21.2
ScriptManager, UpdatePanel
und UpdateProgress im Webdesigner
|

Abbildung 21.3 Lösung mit partieller Seitenerzeugung
UpdateProgress
Mit einem
UpdateProgress
-Steuerelement kann der Entwickler ergänzend zu einem
UpdatePanel
-Steuerelement definieren, dass während der Aktualisierung eines
Seitenfragments der Endbenutzer eine bestimmte Anzeige, z. B.
ein animierte GIF-Grafik, sehen soll. Außerdem kann man definieren, dass der
Endbenutzer die Aktion über eine Schaltfläche oder einen Link abbrechen kann.
Dazu muss man clientseitig
abortPostBack()
aufrufen, siehe nächstes Beispiel.
HINWEIS
Ein
UpdateProgress
-Steuerelement wird bei jedem AJAX-Rückruf durch irgendein
UpdatePanel
-Steuerelement auf der Seite angezeigt. Die Anzeige kann aber auf ein
bestimmtes
UpdatePanel
-Element reduziert werden.
Beispiel
In dem vorherigen Beispiel war in der Ergebnisseite bereits
eine Fortschrittsanzeige enthalten. Hier folgt der dafür notwendige XML-Code.
Einsatz des UpdateProgress-Steuerelements
Trigger
Alle Steuerelemente, die innerhalb eines
UpdatePanel
-Steuerelements liegen und einen Rückruf zum Server auslösen (weil sie
entweder eine Schaltfläche oder mit
AutoPostback="True"
versehen sind), lösen eine Aktualisierung des Inhalts des
UpdatePanel
-Steuerelements aus. Auch ein anderes (außen liegendes) Seitenelement
oder ein Timer können eine Aktualisierung anstoßen. Dafür muss der
Webentwickler dem
UpdatePanel
-Steuerelement einen Trigger zuordnen. Die Maßeinheit beim Trigger sind
Millisekunden (Standardwert 60.000, also einmal pro Minute).
Beispiel
Das folgende Listing sorgt dafür, dass das Steuerelement
»C_Ort«, das nicht im
UpdatePanel
-Inhalt liegt, eine Aktualisierung des
UpdatePanel
-Inhalts anstößt, wenn das Ereignis
SelectedIndexChanged()
ausgelöst wird.
<asp:UpdatePanel
ID="UpdatePanel1" runat="server"
UpdateMode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="C_Ort"
EventName="SelectedIndexChanged" />
</Triggers>
…
</asp:UpdatePanel>
Listing
21
.3 Trigger beim
UpdatePanel
Timer
Ein
Timer
-Steuerelement ist ein Serversteuerelement, das JavaScript zum Browser
sendet, mit dem in einem periodischen Intervall ein Skript gestartet werden
kann oder mit dem ein
UpdatePanel
-Steuerelement aktualisiert werden kann.
Beispiel
Die folgende Abbildung zeigt eine Fortschrittsanzeige, die
serverseitig auf Basis des tatsächlichen Arbeitsfortschritts einer lang
anhaltenden Aktion in einem Hintergrund-Thread entsteht. Die
Fortschrittsanzeige basiert auch auf der partiellen Seitenerzeugung. Der
Browser fragt durch einen Timer einmal pro Sekunde nach dem aktuellen
Seitenfragment für die Fortschrittsanzeige. Die Verbindung eines
UpdatePanel
-Steuerelements mit einem Timer-Steuerelement sorgt für das periodische
Aktualisieren des Seitenteils.

|
Abbildung
21
.4 Fortschrittsanzeige auf Basis eines
UpdatePanel-Steuerelements
|
<asp:ScriptManager ID="C_SM"
runat="server" />
<asp:Timer ID="C_Timer" runat="server"
Enabled="true" Interval="1000">
</asp:Timer>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Literal ID="C_Refresh"
runat="server"></asp:Literal>
Fortschritt:
<asp:Label ID="C_Fortschritt" runat="server"
Text="Label"></asp:Label>
<div style="background-color: black; height: 1px; width:
400px">
</div>
<asp:Literal ID="C_Balken" runat="server">
<div
style="background-color:red;height:10px;width:400px"></div>
</asp:Literal>
<div style="background-color: black; height: 1px; width:
400px">
</div>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="C_Timer" />
</Triggers>
</asp:UpdatePanel>
Listing 21.4 Timer, Trigger und UpdatePanel
Webservice-Aufrufe
An dem vorherigen Beispiel der Fortschrittsanzeige wird
deutlich, dass auch bei der partiellen Seitenerzeugung der Overhead immer noch
groß sein kann: Jedes Mal sendet der Server die im Panel enthaltenen HTML-Tags
zur Erzeugung der Balken zum Browser. Eigentlich braucht der Browser aber nur
eine einzige Zahl, aus der er die Darstellung selbst erzeugen könnte. ASP.NET
AJAX bietet daher ein zweites Verfahren an, bei dem einzelne elementare Daten
oder auch komplexere Datenstrukturen ohne die Layout-Information im Stil eines
Remote Procedure Call (RPC) zum Browser übermittelt werden. Auf der Serverseite
definiert der Entwickler eine .NET-Methode mit Parametern und Rückgabewert. Der
Client erhält über einen generierten Proxy die Möglichkeit, diese Methode wie
jede andere JavaScript-Methode aus JavaScript heraus aufzurufen. Die dem
Methodenaufruf zugrunde liegende Verwendung des
XmlHttpRequest
-Objekts verbirgt der Proxy ebenso vor dem Benutzer wie die
browserspezifischen Eigenarten dieses Objekts.
Das Interessante an den Browser-Rückrufen ist, dass
Microsoft auf einem Konzept aufsetzt, welches .NET sowieso schon seit Version
1.0 bietet: ASP.NET-basierte Webservices (ASMX). Ein mit ASP.NET erzeugter
XML-Webservice tauscht normalerweise SOAP-Nachrichten aus und stellt die
Metadaten als WSDL-Dokument bereit. Für die AJAX Library hat Microsoft sich
aber für ein Verfahren entschieden, das dem Browser die Last der Auswertung von
XML-Dokumenten abnimmt. Wenn der Entwickler einen XML-Webservice zusätzlich mit
der Annotation
[ScriptService
]
ausstattet, erzeugt der Webservice durch Anhängen von »/js« an den URL
plötzlich JavaScript-Code für einen Browser statt WSDL und serialisiert statt
in SOAP-Format in Form der JavaScript Object Notation (JSON). Diesen Ablauf
veranschaulicht die folgende Abbildung.

Abbildung 21.5 AJAX-Aufrufe von ASMX-Webservices
Der auch in diesem Fall notwendige ScriptManager erhält den
URL des Webservice. Visual Studio lässt die Wahl, ob der von dem Webservice
erzeugte JavaScript-Proxy-Code jeweils ad hoc von dem Webservice abgerufen oder
in die Webseite eingebettet werden soll. Auf den Webservice kann man dann aus
einer beliebigen JavaScript-Routine über den Namen der Klasse und der Methode
zugreifen.
Dabei hat die JavaScript-Methode aber immer zwei Parameter
mehr als die ursprüngliche Methode. Die zusätzlichen beiden Parameter erfüllen
das »A« in AJAX, die Asynchronität. Der Aufrufer erhält keinen Rückgabewert von
dem Methodenaufruf, sondern gibt zwei JavaScript-Routinen an, die im Erfolgs-
bzw. Fehlerfall aufzurufen sind.
ACHTUNG
WCF-Dienste können in der
ASP.NET AJAX Version 1.0 noch nicht verwendet werden. Dies will Microsoft aber
in der nächsten Version von ASP.NET AJAX ergänzen. Zu beachten ist ferner, dass
man immer nur Webservices auf dem gleichen Webserver aufrufen kann, auf dem
auch die Webseite liegt. Dies ist eine Sicherheitsfunktion des
XmlHttpRequest
-Objekts. Zum Aufruf von Webservices auf anderen Webservern (z. B.
für Mashups) muss der Webentwickler einen lokalen Wrapper erstellen. In der
zukünftigen ASP.NET AJAX Version 2.0 will Microsoft dies durch deklarierbare
Webservices-Bridges vereinfachen.
Beispiel
In dem folgenden Beispiel werden drei
AJAX-Webservice-Aufrufe verwendet:
§
Flugnummernsuche: Beim Klick auf die »Prüfen«-Schaltfläche werden
Informationen zu dem in das Textfeld eingegebenen Flug abgeholt.
§
Abflugortauswahl: Bei der Auswahl eines Abflugortes wird die Liste
der erreichbaren Zielorte geholt.
§
Zielauswahl: Bei der Auswahl eines Zielortes wird der nächste
verfügbare Flug angezeigt.

|
Abbildung 21.6 Beispiel, in dem ASP.NET AJAX-Webservice-Aufrufe
verwendet werden
|
Das folgende Listing zeigt einen mit
[ScriptMethod]
annotierten ASMX-Webservice (in Ausschnitten), der im Hintergrund der Lösung
arbeitet. Durch nur eine einzige zusätzliche Codezeile wird aus einem
ASMX-Webservice ein Endpunkt für AJAX-Aufrufe des Webbrowsers.
WebService(Namespace="http://IT-Visions.de/wwwings",
Name="WorldWideWings Flugplan-Webservice",
Description="Webservices für den WorldWideWings-Flugplan!"),
WebServiceBinding(ConformsTo=WsiProfiles.BasicProfile1_1, EmitConformanceClaims=true)]
[System.Web.Script.Services.ScriptService()]
public class WWWingsFlugplanService : System.Web.Services.WebService
{
[WebMethod()]
public de.WWWings.Flug GetFlight(long FlightNo)
{
return de.WWWings.FlugBLManager.HoleFlug(FlightNo);
}
…
}
Listing 21.5 Einsatz von [ScriptService]
Bei einem solchen Webservice-Aufruf geht es auch auf dem
Client nicht ohne eigenen Programmcode, denn der Entwickler muss festlegen,
welches Seitenelement die Aktion auslöst, woher die Parameter kommen und vor
allem wie das Ergebnis in der Seite darzustellen ist. Hier vermisst man noch
von der serverseitigen Programmierung gewohnte
IntelliSense-Eingabeunterstützung mit Befehlsvervollständigung und einen guten
Debugger. Visual Studio 2005 liefert zwar einen JavaScript-Debugger mit; dieser
ist aber umständlich. Eine bessere Unterstützung für AJAX-Entwickler verspricht
Microsoft mit der nächsten Version von Visual Studio.
In dem folgenden Listung sieht man anschaulich, dass das
von dem JavaScript-Proxy gelieferte Ergebnis des AJAX-Aufrufs keine Sammlung
von Einzelwerten, sondern ein JavaScript-Objekt mit der gleichen Struktur wie
das serverseitige .NET-Objekt
Flug
ist, also Attribute
FlugNr
,
AbflugOrt
,
ZielOrt
etc. besitzt.
<!---
Client-Skript --->
<script type="text/javascript">
function PageMethodCall()
{
var testString =
"PageMethodCall";
PageMethods.EchoString(testString, OnSucceeded);
}
// This is the callback function
// that process the page method call
// return value.
function OnSucceeded(result)
{
// Display the result.
var RsltElem = document.getElementById("Results");
RsltElem.innerHTML = result;
}
</script>
<script type="text/javascript"
language="javascript">
// ---------------------------------------------------------------
// Hilfsroutinen
// ---------------------------------------------------------------
// Wird aufgerufen, wenn es auf dem Server zu einem Fehler kam
function Fehler( error )
{
alert("Fehler bei der AJAX-Verarbeitung auf dem Server: " +
error.get_message());
}
// ---------------------------------------------------------------
// Ereignisbehandlung für Flugnummernsuche
// ---------------------------------------------------------------
// Ereignisbehandlung für Flugnummerneingabe
function FlugNachNummerSuchen()
{
//debug.fail("test");
document.all.C_Ergebnis1.innerHTML = "Ihre Eingabe wird geprüft...";
// Flugnummer auslesen
var FlugNr = document.forms[0].C_FlugNr.value;
// AJAX-Aufruf gegen ASMX-Webservice
WWWingsFlugplanService.GetFlight(FlugNr,FlugNachNummerSuchen_Ergebnis,Fehler);
// AJAX-Aufruf gegen Seitenmethode
//PageMethods.HoleFlug(n,FlugNachNummerSuchen_Ergebnis,
Fehler);
}
// Rückruf
function FlugNachNummerSuchen_Ergebnis(result)
{
document.all.C_Link.href="ajax/Fortschrittsanzeige_ATLAS.aspx?id=" +
result.FlugNr;
ausgabe = "Sie haben gewählt:<br>Flug " + result.FlugNr +
" von " + result.AbflugOrt + " nach " + result.ZielOrt +
" und hat " + result.FreiePlaetze + " freie Plätze!";
document.all.C_Ergebnis1.innerHTML = ausgabe;
document.all.C_Link.style.visibility ="visible"
}
// ---------------------------------------------------------------
// Ereignisbehandlung für Abflugauswahl
// ---------------------------------------------------------------
function AbflugortAuswahl() {
C_Abflugort = $get('<%= this.C_Abflug.ClientID %>');
//alert("OK");
// Ermittlung der Option
var abflug =
C_Abflugort.options[C_Abflugort.selectedIndex].value;
// Callback zum Server
document.all.C_Ergebnis2.innerHTML =
"Lade Zielorte...";
WWWingsFlugplanService.GetDestinations(abflug,AbflugortAuswahl_Ergebnis);
}
// Rückruf
function AbflugortAuswahl_Ergebnis(result)
{
C_Zielort =
document.getElementById('<%= this.C_Zielort.ClientID %>');
document.all.C_Ergebnis2.innerHTML = result.length + " Zielorte wurden
gefunden.";
// Leeren der Liste
while (C_Zielort.options.length > 0) { C_Zielort.remove(0); }
// Fuellen der Liste
for (var i=0; i<result.length; i++) {
//C_Zielort.visible =
true;
var Option =
document.createElement("option");
Option.value =
result[i];
Option.text = result[i];
C_Zielort.add(Option);
}
}
// ---------------------------------------------------------------
// Ereignisbehandlung für Zielauswahl
// ---------------------------------------------------------------
// Ereignisbehandlung für Zielortauswahl
function ZielortAuswahl() {
C_Abflugort =
document.getElementById('<% = this.C_Abflug.ClientID %>');
C_Zielort =
document.getElementById('<%= this.C_Zielort.ClientID %>');
// Ermittlung der Option
var abflugort = C_Abflugort.options[C_Abflugort.selectedIndex].value;
var
zielort =
C_Zielort.options[C_Zielort.selectedIndex].value;
ausgabe = "Sie haben gewählt:<br>Route von " + abflugort +
" nach " + zielort;
document.all.C_Ergebnis1.innerHTML = ausgabe;
document.all.C_Link.href="ajax/Fortschrittsanzeige_ATLAS.aspx?von="
+ abflugort +"&nach=" + zielort;
document.all.C_Link.style.visibility ="visible"
}
</script>
Listing
21
.6 Das clientseitige
Skript für das Beispiel
Bei dem AJAX-Aufruf eines ASMX-Webservice sind die
HTTP-Header größer als die eigentliche Nutzlast, wie man im Netzwerkmonitor
Fiddler [FID01] (siehe folgende Abbildung) erkennt.

Abbildung 21.7 Ein AJAX-Webservice-Aufruf mit einem HTTP-Monitor
betrachtet
TIPP
Neben der Möglichkeit zum
Aufruf von Webservices, die in eigenständigen ASMX-Dateien realisiert sind,
kann der AJAX-Entwickler auch die Option nutzen, Methoden in einer normalen
ASPX-Seite via AJAX aufzurufen: Dazu muss die Methode mit
[WebMethod]
annotiert sein (im Widerspruch zu
[ScriptService]
bei .asmx-Dateien) und dann im Browser über den
feststehenden Objektnamen
PageMethods
angesprochen werden.
Als vordefinierte Webservices stellt ASP.NET AJAX die
Authentifizierung und den Personalisierungsdienst von ASP.NET zur Verfügung.
Somit kann der Webentwickler den Anmeldedialog und Personalisierung von
Webseiten durch AJAX realisieren.
Extender
Ein Extender ist in der Sprache von ASP.NET AJAX eine
Erweiterung, die ein bestehendes (»dummes«) HTML-Steuerelement um zusätzliche
Funktionen erweitert. Ein Extender besitzt immer eine clientseitige Komponente
in JavaScript; eine serverseitige Komponente ist optional.
Das AJAX Control Toolkit enthält zahlreiche Extender und
darauf basierende Client-Steuerelemente (allgemein DHTML-Widgets genannt).
Beispiele für diese Steuerelemente sind:
§
Das
Accordion
-Steuerelement, das Bereiche in einer kleinen Animation auf- und
zuklappt, arbeitet rein clientseitig. Allerdings wurde sowohl das auf dem
Client notwendige HTML als auch das zugehörige JavaScript auf dem Server
erzeugt.
§
Mit dem
ReorderList
-Steuerelement kann ein Endbenutzer rein clientseitig den Inhalt und die
Sortierung einer Liste bestimmen.
§
Das
CascadingDropDown
-Steuerelement fragt nach der Auswahl in einem Feld beim Webserver nach,
welche Daten in das nächste Auswahlfeld gehören.
Zusammen mit dem AJAX Control Toolkit liefert Microsoft
auch eine Sammlung von Beispielen, die jedes einzelne Steuerelement in Aktion
zeigen (siehe Abbildung).

Abbildung 21.8 Steuerelemente im AJAX Control Toolkit
ACHTUNG
Das Control Toolkit ist
kein klassisches Microsoft-Produkt, sondern Microsoft bezeichnet es als
»Gemeinsames Projekt von Microsoft und der .NET Community«, das im Rahmen des
Projektportals Codeplex zur Verfügung steht. Jedermann hat die Möglichkeit,
sich für eine Mitarbeit bei dem Projekt zu bewerben. Zumindest die zum
Redaktionsschluss verfügbare Version weist noch deutliche Fehler auf,
insbesondere im Zusammenspiel mehrerer Extender auf einer Seite (siehe dazu
[HS06]).
Ausblick
Zukünftig wird man in ASP.NET AJAX noch mehr Steuerelemente
sehen, die primär auf dem Client arbeiten. In den ursprünglichen Vorabversionen
von »Atlas« waren einige Funktionen enthalten, die es in der ASP.NET AJAX 1.0
bzw. dem zugehörigen Control Toolkit nicht gibt. Dort bietet Microsoft für
JavaScript die Abstraktion, die der Webentwickler schon von ASP.NET kennt.
Zukünftig gibt es neben den Server-Steuerelementen, die ASP.NET in HTML, CSS
und JavaScript umwandelt, auch Client-Steuerelemente, die JavaScript in die
gleichen Ergebnisformate transformiert. Wie bei den Serversteuerelementen kann
man das XML zur Deklaration verwenden: Microsoft spricht daher von XML Script.
Microsoft überträgt damit das Abstraktionsmodell von ASP.NET auf den Browser.
Zu den Highlights von XML Script werden eine eigene
Animationssprache und die clientseitige Datenbindung gehören. Der Webentwickler
hat dann bei überschaubaren Datenmengen die Wahl, die Daten in einem Rutsch zum
Browser zu befördern und Suchen, Sortieren und Blättern ohne einen einzigen
Roundtrip zum Server zu implementieren.
HINWEIS
Zum Redaktionsschluss
dieses Beitrags gibt es bereits eine Vorabversion der künftigen
ASP.NET-AJAX-Version unter dem Titel »ASP.NET AJAX Futures«.