This content was uploaded by our users and we assume good faith they have the permission to share this book. If you own the copyright to this book and it is wrongfully on our website, we offer a simple DMCA procedure to remove your content from our site. Start by pressing the button below!
Christian Wenz Deutsche Obersetzung von Lars Schulten
Programmieren mit ASP.NET AJAX
C hristian Wenz
Deutsche Übersetzung von Lars Schulten
Beijing . Cambridge . Farnham . Köln
Q'REILLY®
. Paris . Sebastopol . Taipei . Tokyo
Die Informationen in diesem Buch wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Verlag, Autoren und übersetzer übernehmen keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene Fehler und deren Folgen. Alle Warennamen werden ohne Gewährleistung der freien VelWendbarkeit benutzt und sind möglicheIWeise eingetragene Warenzeichen. Der Verlag richtet sich im Wesentlichen nach den Schreibweisen der Hersteller. Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der VelVielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen. Kommentare und Fragen können Sie gerne an uns richten: O'Reilly Verlag Balthasarst r . 8 1 50670 Köln Tel.: 0221/9731600 Fax: 0221/9731608 E-Mail: [email protected]
Die Darstellung einer Wurzelschnecke im Zusammenhang mit dem Thema ASP.NET AJAX ist ein Warenzeichen von O'Reilly Media, Inc.
Bibliografische Information Der Deutschen Bibliothek Die Deutsche Bibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie; detaillierte bibliografische Daten
sind im Internet über hup:/Idnb.ddb.de abrutbar.
Übersetzung und deutsche Bearbeitung: urs Schulten, Köln Lektorat: AJexandra Follenius, Köln Korrektorat: Friederike Daenecke, Zülpich Satz: Tim Mergemeier, reemers publishing services gmbh, Krefeld; www.reemers.de
Umschlaggestaltung: Karen Montgomery, Sebastopol & Michael Oreal, Köln Produktion: Karin Driesen, Köln Belichtung, Druck und buchbinderische Verarbeitung: Druckerei Kösel, Krugzell;
www.koeselbuch.de
ISBN-13 978-3-89721-480-4 Dieses Buch ist auf 100% chlorfrei gebleichtem Papier gedruckt.
Die ASP.NET AJAX-JavaScript-Erweiterung verwenden ASP. NET AJAX-Kürzel und -Hilfsfunktionen Ernreirerungen für vorhandene JavaScript-Objekte . . . . . . . . . ASP.NET AjAX-OOP-Features für javaseript . . . . . . . . . . . . Clientversionen von .NET-Klassen Zusammenfassung Zum weiteren Lesen .
Eines der ersten Compute rbücher, die ich besaß und das erste von O'Reilly in meinem Fundus, ist Programmieren mit Perl - damit stehe ich sicher nicht alleine da. Ich persön lich fand das Buch furchtbar - damit stehe ich ziemlich alleine da. Später, als ich mir anderweitig Perl beigebracht habe und mit der »Schweizer Kettensäge der Programmier sprachen« gut zurechtkam, nahm ich das Buch wieder in die Hand, und dann fand ich es toll. Was mir aber vor allem an dem Buch in Erinnerung geblieben ist, ist das spezielle Vor wort von Larry Wall für die deutsche Ausgabe. Er erzählt dort von einem deutschen Spruch, der im Flur seiner Eltern hing. Ich war sowohl begeistert von Larrys deutschen Wurzeln als auch von der Qualität der deutschen Übersetzung an sich. Im IT-Bereich ist die meiste Literatur - zumindest kurz nach Erscheinen einer neuen Version eines Pro dukts ode r einer Technologie - zunächst auf Englisch verfügbar. Ich lese gerne englische Bücher, bin aber natürlich beim Erfassen und Verstehen von Texten in meiner Mutter sprache schneller. Zumindest, sofern das Deutsch nicht holprig ist - ein Manko vieler Übersetzungen (aus gewissen Gründen möchte ich hier nicht den ersten Stein werfen). Ich habe im Laufe der Zeit immer wiede r bestätigt bekommen, dass die Buchübersetzun gen aus dem Englischen bei O'Reilly einen sehr hohen Qualitätsstandard haben. Wohl auch deswegen nennt O'Reilly bei den eingedeutschten Tite ln immer den oder die Über setze r direkt auf dem Cover. Ich weiß es noch ganz genau: Bei Programmieren mit Perl war es Peter Klicman. Ein wenig späte r fasste ich den Entschluss, auch irgendwann mal ein Buch schreiben zu wollen. Irgendwann. Nur eines. Ich war jung und naiv. Als sich das Buchregal so langsam mit eigenen Ergüssen füllte , schraubte ich die Ziele etwas höher: Ein Titel für O'Reilly wäre doch eine schöne Sache, am besten mit einem exotischen Tier auf dem Cover. Doch bis dahin war es ein weiter Weg: Bei O'Reilly Deutschland war die Themenfindung schwierig, da viele spannende Technologien bereits von den amerikanischen Kollegen abgehandelt wurden; O'Reilly USA hingegen akzeptiert in der Regel nur Muttersprachler als Autoren.
I XI
Auf der PDC (Professional Developers Conference) 2005 in Los Angeles konnte ich jedoch die Gelegenheit beim Schopfe packen. Gerüchte über ein Ajax-Framework von Microsoft gab es schon länger, und auf der Konferenz wurde es das erste Mal gezeigt. Direkt nach dem Vortrag fing ich an, ein Buchkonzept zu schreiben. Irgendwann am nächsten Tag hatte ich einen Zwischenstand, den ich an O'Reilly schickte (Website-Rub rik »Writing for O'Reilly« ) - das nennt man wohl Kaltakquise. Und tatsächlich meldete sich noch am selben Tag ein Lektor, John Osborn, zurück: Er sei auch auf der Konferenz, würde am nächsten Tag abreisen, aber ob wir uns noch treffen wollten? Ich erinnere mich noch lebhaft, wie mich der Wachmann meines Hotels musterte, als ich mich tief in der Nacht in das Business Center schlich, um das mittlerweile fertiggestellte Buchkon zept auszudrucken. Am nächsten Tag schließlich traf ich John, diskutierte mit ihm über das Konzept und konnte ihn auch davon überzeugen, die Muttersprachler-Voraussetzung außen vor zu lassen (meine hart per MAD-Magazine-Abonnement erworbenen Sprachkenntnisse machten sich bezahlt). Nachdem alles Vertragliche geregelt war, machte ich mich ans Schreiben. Die ersten bei den Kapitel schrieb ich am Rande einer Konferenz in San Diego. Während ich im Busi ness Center des Hotels saß, um eine erste Fassung auszudrucken, platzte der Hotel Manager herein, mitsamt eines Kamerateams. Das Business Center nämlich war ein Pro totyp, der auch in anderen Hotels derselben Kette eingesetzt werden sollte. Sie wollten einen Promo-Film dafür drehen und suchten nach ahnungslosen Nutzern. Na, wunder bar: Das Buchprojekt ist noch streng geheim, aber schon auf Film. Ein großer Teil des Buches entstand ebenfalls im Ausland: Im Januar 2006 flog ich auf die Kanaren, um dort eine Zeitlang in Ruhe (und in Wärme) am Manuskript arbeiten zu können. Das war eine sehr interessante Erfahrung: Schon lange war ich internettechnisch nicht mehr auf analoge Telefonleitungen angewiesen. Aber da Atlas, so der damalige Name des Frameworks, kaum dokumentiert war, konnte ich auf Foren, Newsgroups und Online-Dokus kaum zugreifen, es half nur Reverse-Engineering. Im Frühling und Sommer 2006 erschienen verschiedene elektronische Vorabversionen (Rough Cuts) des Buchs, und im September war es schließlich so weit: Die gedruckte Ausgabe erschien. Im September war es leider zwei Wochen später ebenfalls so weit, dass Microsoft den Namen des Frameworks änderte, und auch die Interna wild durcheinan derwürfelte. Es hätte dennoch schlimmer kommen können: Das Atlas-Buch eines Auto renkollegen von mir erschien ein paar Wochen später. Er konnte zwar noch Atlas per Suchen & Ersetzen überall durch »ASP.NET AJAX« (den neuen Framework-Namen) ersetzen, wurde aber auch durch die vielen internen Änderungen kalt erwischt. Die finale Version von ASP.NET AJAX erschien schließlich Ende Januar 2007; zeitgleich begannen die Arbeiten an der neuen Auflage (Motto: Nie wieder Beta-Code!). Wieder gab es ein paar elektronische Vorab-Versionen, und schließlich erschien das gedruckte Buch.
XII I Vorwort zur deutsdum Übersetzung
Zugegeben, die zweite Hälfte des vorhergehenden Satzes ist gelogen. Zu dem Zeitpunkt, zu dem ich das schreibe, ist das Buch »erst« auf dem Weg in den Druck. Denn O'Reilly Deutschland hatte bereits 2006 geplant, eine Übersetzung des Buchs herauszugeben, und arbeitete seitdem fieberhaft daran, die englischen Texte möglichst zeitnah ins Deutsche zu übertragen (das Team erhielt gerüchteweise aus einer anonymen Quelle immer die taufrischen englischen Kapitel). Somit kommt es zu dem seltenen Fall, dass das Original und die Übersetzung zeitgleich erscheinen. Beim Lesen der deutschen Kapitel muss ich allerdings zugeben, dass ich ein wenig erschüttert war: Ich wusste gar nicht, wie gut meine deutsche Schreibe ist! Leider schmü cke ich mich hier mit fremden Lorbeeren: In alter O'Reilly-Tradition war auch dieses Mal ein ausgewiesener Profi für die Übersetzung zuständig, Lars Schulten. Nebenbei ver sorgte er mich mit einigen fachlichen Verbesserungsvorschlägen (nun gut, Errata) und hat damit sowohl das englische als auch das deutsche Buch besser gemacht. Herzlichen Dank dafür! Alexandra Follenius hatte als zuständige Lektorin immer die Fäden in der Hand; vielleicht schafft sie es sogar, die amerikanischen Kollegen in Hinblick auf das Ver öffentlichungsdatum um ein paar Tage zu schlagen. Es ist ein enormer Abstimmungsauf wand, eine Übersetzung zu organisieren, während sich das Originalbuch noch in der Produktion befindet, auch dafür herzlichen Dank. Ebenfalls danke ich Tobias und Yvonne. Bleibt nur noch der Blick in die Zukunft: Was wird Microsoft aus dem Framework machen? Nach dem bösen Blut, das von der letzten Namensänderung verursacht wurde, sind krasse Einschnitte sehr unwahrscheinlich geworden; die viel gerühmte Go-Live Lizenz von Microsoft-Produkten (erlaubt es bei manchen Vorabversionen, diese produk tiv einzusetzen und nährt die Hoffnung, dass die Unterschiede zu den finalen Versionen gering sein werden) wird von der Fachwelt seit dem Umstieg von Atlas auf ASP.NET AJAX eher kritisch wahrgenommen. Denkbar ist eher, dass ASP.NET AJAX in der Zukunft mit weiteren Features versehen wird, die Abwärtskompatibilität jedoch immer gewahrt bleibt. Sollte das wider Erwarten nicht klappen, so kann ich nur mit dem Ende von Larry Walls deutschem Vorwort schließen: »Tja nun. C'est la vie.« Beim finalen Satz ist es freilich egal, wie gut der Übersetzer ist. Christian Wenz August 2007
Vorwort zurdeuuchen Übersetzung I XIII
Einleitung
Die Wikipedia-Seite für Ajax (http://de.wikipedia.org/wiki/Ajax) führt fast 20 verschie dene Bedeutungen für das Wort auf, unter anderen den Namen zweier Figuren in Homers Was (Ajax der Große und Ajax der Kleine), den Namen einer Amsterdamer Fuß ballmannschaft, von ein paar Produkten bzw. Unternehmen, einem Asteroiden und mein persönlicher Liebling - einem Haushaltsreiniger von Colgate. Aber Ajax ist auch der Begriff für eine Sammlung von Technologien, von denen viele sagen, dass sie das Web revolutionieren könnten. Wenn man verschiedenen Weblogs und Online- und Printmedien Glauben schenken darf, ist Ajax die Zukunft der Webentwicklung, die Grundlage des Web 2.0 und wahrscheinlich ein Heilmittel gegen bislang unheilbare Krankheiten. Viele Webentwickler möchten ihren Anwendern ein ausgereifteres Clienterlebnis bieten, wollen (oder können aus praktischen Gründen) aber keine Windows-Clientanwendung schreiben. Ajax könnte genau das sein, was sie brauchen. Es macht Webanwendungen möglich, die sich fast wie Desktop-Anwendungen verhalten und Funktionalitäten wie Tastenkürzel und Drag-and-Drop bieten. ASP.NET »Atlas« war der Codename für eine neue Gruppe von Technologien von Micro soft, die ASP.NET-Entwicklern Ajax-artige Funktionalitäten zur Verfügung stellte und dabei viele der Vorteile für die Ajax-Entwicklung bot, die ASP.NET für die serverseitige Entwicklung bietet. Im Herbst 2006 wurde der endgültige Produktname verkündet: ASP.NET AJAX. (Wie Sie sehen, ist Atlas viel leichter auszusprechen.) Ich habe dem Drang, über Ajax zu schreiben, eine ganze Zeit lang widerstanden. Die Technologien, aus denen Ajax besteht, nutze ich schon seit Jahren, und ich habe auch über alle einzeln schon geschrieben, aber es musste erst Anfang 2005 der Begriff Ajax auf geworfen werden, bevor die Technologie richtig abhob. Meiner Meinung nach hat Cle mens Vasters es am besten ausgedruckt: "Web 2.0 yadda yadda AJAX yaddayadda Profit! (?)« (siehe http://vasters.com/ciemensv/PermaLink,guid,d88c1 1 12-d8da-496e-9fdO8cj03cj55c32.aspx). Der Hype erinnert mich an den Rummel, der vor einigen Jahren XML und Webservices begleitet hat: Alle sprachen davon, aber nur wenige hatten je die Spezifikationen gelesen.
I xv
Nachdem alle wieder auf dem Boden der Tatsachen angekommen sind, hat der Hype echten Anwendungen Platz gemacht, die beide Technologien effizient einsetzen. Ich bin überzeugt, dass Ajax einen ähnlichen Weg gehen, diesen aber schneller durchschreiten wird. Eine kleine Webtour beweist, dass heute schon Massen nützlicher Ajax-Anwendun gen verfügbar sind. Zurück zu meinem Zögern, ein Buch zu Ajax zu schreiben. Die ganze Zeit habe ich mir gesagt, dass man Ajax selbst auf 20 bis 30 Seiten beschreiben könnte. Fügte man ein paar Hintergrundinformationen und Beispiele hinzu, könnte man 75, vielleicht 100 Seiten produzieren. Viele der Ajax-Bücher, die auf dem Markt sind, mussten Verrenkungen machen, um auf eine vertretbare Seitenzahl zu kommen. Meine Meinung dazu hat sich geändert, als ich an der Microsoft Professional Developers Conference in Los Angeles im September 2005 teilnahm und Atlas zum ersten Mal sah. Microsoft kündigte ein Framework an, das Ajax-Funktionalitäten bot, fügte dem aber Steuerelemente und Funktionalitäten hinzu, die das Entwickeln moderner Webanwen dungen leichter machen. Das ist etwas, wo sich das Schreiben lohnt, dachte ich mir. Dann begann ich auf Basis von frühen Vorabversionen von Atlas am Manuskript zu arbeiten. Ich musste es mehrfach umschreiben, wenn ich Hand an einen neuen Vorab Happen von Atlas legen konnte. Das Fehlen einer Dokumentation für die Vorabversio nen zwang mich, die inneren Mechanismen von Atlas zu entschlüsseln. Es kann also sein, dass das Buch ein paar inoffizielle Wege beschreibt, bestimmte Dinge zu erreichen. Im September 2006 wurde Programming Atlas dann veröffentlicht und bot als eines der ersten Bücher zum Thema detailierte Informationen zu dem sich immer noch ändernden Framework. Ende Januar 2007 wurde ASP.NET AJAX in der ersten endgültigen 1 .0-Ver sion veröffentlicht. Das hat eine neue Auflage des Buchs erforderlich gemacht - denn neben der Namensänderung waren auch die inneren Änderungen so umfassend, dass sämtliche bestehenden Anwendungen angepasst werden mussten. Dieses Buch wird Ihnen zeigen, wie Sie professionelle, dynamische Webseiten mit dem Microsoft ASP.NET AJAX-Framework erstellen. Gewisse JavaScript- und ASP.NET Kenntnisse sind erforderlich, aber die JavaScript-Grundlagen werden am Anfang des Buchs behandelt. Ich bin ein großer Anhänger des Prinzips »Ein Beispiel sagt mehr als tausend Worte« . Dieses Buch enthält deswegen eine große Anzahl von Beispielen, die Ihnen die Schlüssel aspekte des ASP.NET AJAX-Frameworks vorführen. Außerdem bin ich jemand, der es vorzieht, sich auf die relevanten Tatsachen zu konzentrieren. Deswegen habe ich kleine Beispiele aufgebaut, die jeweils einen oder zwei Aspekte vermitteln. Ich habe es mit Absicht vermieden, so viele Dinge wie möglich in ein sehr langes Beispiel zu packen. Meine Erfahrung als Autor und Trainer hat mich gelehrt, dass kürzere Beispiele zu besse ren Ergebnissen führen und das Lernen leichter machen. Beachten Sie auch, dass die Beispiele immer sehr allgemein sind. Das bietet Ihnen die Möglichkeit, sie direkt in Ihre eigenen Projekte einzufügen und so zu verändern und zu verbessern, dass Sie Ihren Anforderungen entsprechen. Jedes Beispiel ist in sich abge schlossen, das macht es sehr leicht, die Beispiele (wieder) zu verwenden. XVI I Einleitung
Für wen dieses Buch gedacht ist Dieses Buch wurde für zwei Gruppen von Webentwicklern geschrieben: jene, die ASP.NET nutzen und ihre Anwendungen gern einen Schritt weiter führen möchten, indem sie die Ajax-Technologie einsetzen, sowie für Entwickler, die eine andere Techno logie nutzen, sich aber für das ASP.NET AJAX-Framework interessieren. Es ist auch für JavaScript-Programmierer geeignet, die gern einige der Kopfschmerzen vermeiden wol len, die das Erfordernis, browserübergreifenden Code zu schreiben, verursachen kann. Die Sprachen, die in diesem Buch verwendet werden, sind C# und JavaScript. Wenn Sie mehr Informationen zu einer dieser Sprachen brauchen, finden Sie bei O'Reilly einige solide Einführungen in beide.
Der Aufbau dieses Buches Dieses Buch ist in fünf Teile (und einen Anhang) aufgeteilt. Jeder Teil behandelt einen abgeschlossenen Block aus dem ASP.NET-AJAX-Universum, wobei jedoch auch immer wieder teilübergreifend verwiesen wird. Teil I, Grundlagen, verrät alles Wissenswerte über die technischen Hintergründe von ASP.NET AJAX, JavaScript und Ajax. •
Kapitel 1, ASP.NET AJAX, Ajax und ASP.NET, bietet einen ersten Überblick über Ajax und das ASP.NET AJAX-Framework, behandelt dann die Installation von ASP.NET AJAX, bietet einen Überblick über seine Struktur und ein erstes einfaches Beispiel.
•
Kapitel 2, JavaScript, ist eine kompakte Einführung in JavaScript. Obwohl ASP.NET AJAX sich alle Mühe gibt, die Details vor dem ASP.NET-Programmierer zu ver bergen, sind JavaScript-Kenntnisse in gewissem Umfang erforderlich, wenn man ASP.NET AJAX wirklich beherrschen will.
•
Kapitel 3, Ajax, erklärt die Technologie hinter dem Hype. Auf weniger als 20 Seiten erfahren Sie, was im Hintergrund passiert, wie Ajax funktioniert und worum es dabei wirklich geht.
Teil 11, ASP.NET AJAX Extensions, behandelt das Hauptpaket von ASP.NET AJAX, die ASP.NET AJAX Extensions. Microsoft gewährt darauf 10 Jahre Support, und Sie sehen die wichtigsten Features im Einsatz. •
Kapitel 4, Die ASP.NET AJAX-JavaScript-Erweiterung verwenden, beschreibt, wie ASP .NET AJAX die Funktionalität von clientseitigem JavaScript bereichert, indem es ihm neue OOP-artige Features hinzufügt und sogar einige Klassen des .NET Frame works reimplementiert, damit sie auf der Clientseite verwendet werden können.
•
KapitelS, Webservices, befasst sich mit XML-Webservices. Auch wenn sich ASP.NET AJAX auf die clientbasierte Entwicklung konzentriert, bietet es auch Features für serverseitige Webservices. Das schließt Features für das Error-Handling und die Sitzungsunterstü tzung ein. Einleitung I XVII
•
Kapitel 6, UpdatePanel: Nur Teile einer Seite aktualisieren, führt das UpdatePanel Steuerelement ein, das einzelne Teile einer Webseite unabhängig vom Rest der Seite aktualisierbar macht, ohne dass dazu die gesamte Seite aktualisiert werden muss. Das ist eines der wichtigsten Elemente von ASP.NET AJAX.
•
Kapitel 7, Den ASP.NET AJAX-Profildienst nutzen, führt aus, wie ASP.NET AJAX einen JavaScript-Zugriff auf die ASP.NET 2.0 Profil-AP! bietet.
•
Kapitel 8, Den ASP.NET AJAX-Authentifizierungsdienst nutzen, erklärt, wie Java Script an die ASP.NET 2.0-Formularauthentifizierungs-API anknüpfen kann.
•
Kapitel 9, Anwendungen lokalisieren und globalisieren, behandelt das immer wichti ger werdende Thema, Webanwendungen zur Verfügung zu stellen, die mit mehre ren Sprachen und regionalen Einstellungen arbeiten.
Teil IU, ASP.NET AJAX Control Toolkit, stellt ein Community-Projekt von Microsoft vor, das zahlreiche zusätzliche Steuerelernente für ASP.NET AJAX enthält. Sie erfahren auch, wie Sie selbst Teil dieser Community werden können. •
Kapitel 10, Das Control Toolkit verwenden, stellt das ASP.NET AJAX Control Toolkit vor, eine Sammlunge beeindruckender Serversteuerelemente, die mit Ajax-Features angereichert sind.
•
Kapitel 11, Einer Webseite Animationen hinzufügen, stellt das Animations-Frame work vor, das Teil des ASP.NET AJAX Control Toolkits ist.
•
Kapitel 12, Autovervollständigung für Benutzereingaben, Sporn-Bekämpfung und mehr, zeigt die Höhepunkte (auch wenn man da sicher anderer Meinung sein kann) des ASP.NET AJAX Control Toolkits, und demonstriert die Vielschichtigkeit des Toolkits und behandelt auch einige praxistaugliche Tipps- und Tricks.
•
Kapitel 13, Benutzerdefinierte Steuerelemente schreiben und zur Gemeinschaft beitra gen, erklärt, wie man mit der Control Toolkit-Infrastruktur eigene Steuerelemente schreibt und wie man zu ihnen beiträgt oder Patches für vorhandene Steuerele mente zum Toolkit-Projekt beisteuert.
Teil IV, ASP.NET AJAX Futures, dreht sich um Microsoft-Erweiterungen zu ASP .NET AJAX, die es (noch) nicht ins Kernpaket geschafft haben. Vieles kann sich noch ändern, manche Features schaffen es vielleicht nie in die ASP.NET AJAX Extensions, aber Sie können die Funktionalitäten jetzt schon einsetzen. •
Kapitel 14, Clientsteuerelemente, beschreibt die clientseitigen Steuerelernente, die Teil des ASP.NET AJAX Futures CTP sind. Diese vereinfachen den Zugriff auf HTML-Elemente mit JavaScript über eine konsistente API.
•
Kapitel !5, Datenbindung und Validierung, zeigt, wie man dank des ASP.NET AJAX Futures CTP eine clientseitige Datenbindung zwischen (Client-)Steuerelementen implementiert.
XVIII I Einleitung
•
Kapitel 16, Verhalten und Komponenten verwenden, stellt Ihnen die eingebauten Verhalten von ASP.NET AJAX vor und zeigt Ihnen, wie man ihre Funktionalität an clientseitige Steuerelemente und Komponenten bindet.
•
Kapitel l?, Serverdaten verwenden, erklärt, wie Sie eine Verbindung zu einer Daten bank herstellen. ASP.NET AJAX kann über besonders aufgebaute Webservices an Datenquellen geknüpft werden und macht die Datenbindung ohne Seitenaktualisie rungen so ziemlich einfach. Die ASP.NET AJAX Futures bieten auch spezielle client seitige Steuerelemente für die Anzeige von Daten.
•
Kapitel 18, Entfernte Webservices nutzen, hilft Ihnen, die Same-Origin-Policy von JavaScript zu umgehen, und ermöglicht Ihnen über eine serverseitige Bridge, ent fernte Webservices aufzurufen.
•
Kapitel 19, Animationen verwenden, demonstriert einige Animations-Features im ASP.NET AJAX Futures UP.
•
Kapitel 20, Lesezeichen, Zurück- und Vor-Button reparieren, bietet mögliche Lösun gen für zwei der nervendsten Probleme mit Ajax-Anwendungen (die das standard mäßige Browserverhalten brechen).
•
Kapitel 21, Webparts, zeigt, dass ASP.NET AJAX-Webparts Dinge tun können, die ASP.NET-Webparts nicht tun können, dazu zählt auch browserübergreifendes Drag-and-Drop.
Teil V, Microsoft AJAX Library, stellt eine Ajax-Bibliothek von Microsoft vor, die nur aus JavaScript-Code besteht. •
Kapitel 22, ASP.NET AJAX mit anderen Servertechnologien verwenden, beweist, dass einige Teile der Microsoft Ajax Library nicht an ASP.NET 2.0 gebunden sind. Eine Beispielanwendung in PHP zeigt, wie man diese beiden Welten verbindet.
Anhang A, ASP.NET AJAX-Anwendungen debuggen, beschreibt, wie man in ASP.NET AJAX-Anwendungen Fehler findet, und stellt einige unumgängliche Browserwerkzeuge vor. Anhang B, XMLHttpRequest-Referenz, führt wichtige Methoden und Eigenschaften des XMLHttpRequest-Objekts auf. Anhang C, DOM-Referenz, beschreibt wichtige JavaScript DOM-Methoden. Anhang D, ASP.NET AJAX-Referenz, führt die wichtigsten Methoden auf, die das ASP.NET AJAX-Framework bietet. Anhang E, Referenz zur deklarativen Verwendung von ScriptManager, UpdatePanel, UpdateProgress und Timer, dokumentiert die Eigenschaften dieser vier Schlüssel-Server steuerelemente von ASP.NET AJAX.
Einleitung I XIX
Was Sie brauchen, um dieses Buch verwenden zu können Die Beispiele in diesem Buch erfordern nur ASP.NET 2.0, das in der frei verteilbare Ver sion des .NET Frameworks enthalten ist. Um ASP.NET und ASP.NET AJAX richtig zu nutzen, sollten Sie allerdings eines der IDE-Angebote von Microsoft nutzen. Visual Web Developer 2005 Express Edition (VWD) ist kostenlos_ Vi,ual Studio 2005 (in seinen ver schiedenen Formen) ist das kommerzielle Paket mit mehr Funktionalitäten. Beide sind vollkommen für die Arbeit mit den Beispielen in diesem Buch geeignet.
Typographische Konventionen In diesem Buch werden die folgenden typographischen Konventionen verwendet:
Kursiv Zeigt Menü-Überschriften, -Optionen, -Buttons und Tastenkürzel (wie Alt und Strg) sowie neue Begriffe, URLs, E-Mail-Adressen, Dateinamenserweiterungen, Pfadna men, Verzeichnisse und Unix-Werkzeuge an.
Nicht- Proportionalschrift Zeigt Befehle, Optionen, Schalter, Variablen, Attribute, Schlüssel, Funktionen, Typen, Klassen, Namensräume, Methoden, Module, Eigenschaften, Parameter, Werte, Objekte, Events, Event-Handler, XML-Tags, HTML-Tags, Makros, den Inhalt von Dateien oder die Ausgabe von Befehlen an.
Nicht-Proportionalschrift fett
Wird verwendet, um Codeteile hervorzuheben. Nicht-Proportionalschrijt kursiv Zeigt Text, der durch Werte ersetzt werden muss, die der Benutzer vorgibt. .. ,
•• ...,.,"":
[B,,' ,
•
:
Dieses Symbol kennzeichnet einen Tipp, Vorschlag oder allgemeinen H-InwelS.
--
An diesem Symbol erkennen Sie eine Warnung.
Verwendung der Codebeispiele Dieses Buch soll Ihnen bei Ihrer Arbeit helfen. Es ist allgemein erlaubt, den Code aus die sem Buch in Ihren Programmen und Dokumentationen weiterzuverwenden. Hierfür ist es nicht notwendig, uns um Erlaubnis zu fragen, es sei denn, es handelt sich um eine grö ßere Menge Code. So ist es beim Schreiben eines Programms, das einige Codeschnipsel dieses Buchs verwendet, nicht nötig, sich mit uns in Verbindung zu setzen; beim Verkauf oder Vertrieb einer CD-ROM mit Beispielen aus O'Reilly-Büchern dagegen schon. Das
xx I Einleitung
Beantworten einer Frage durch das Zitat von Beispielcode erfordert keine Erlaubnis. Ver wenden Sie einen erheblichen Teil des Beispielcodes aus diesem Buch in Ihrer Dokumen tation, ist dagegen unsere Erlaubnis nötig. Eine Quellenangabe ist zwar erwünscht, aber nicht obligatorisch. Hierzu gehört in der Regel die Erwähnung von Titel, Autor, Verlag und ISBN, zum Beispiel: »Programmieren mit ASP.NET AJAX von Christian Wenz. Copyright 2007 O'Reilly Verlag, ISBN 978-389721-480-4.« Falls Sie sich nicht sicher sind, ob die Nutzung der Codebeispiele außerhalb der hier erteilten Erlaubnis liegt, nehmen Sie bitte unter der Adresse [email protected] takt mit uns auf.
Die Codebeispiele zu diesem Buch Es gibt eine deutsche Website von O'Reilly, auf der Sie Beispiele und weitere Informa tionen zu diesem Buch finden können:
http://www.oreilly.de/catalog/aspajaxger/ Die in diesem Buch abgedruckten Codebeispiele stehen dort zum Herunterladen zur Ver fügung. Bitte klicken Sie auf den Beispiel-Link auf der Katalogseite zum Buch.
Danksagungen (1. Auflage) Die Arbeit an diesem Buch hat sich als eine gewaltige Aufgabe herausgestellt. Das Fehlen einer Dokumentation, Änderungen von einer Version zur nächsten und die Komplexität des JavaScript-Debuggings haben zu vielen Fehlern und Experimenten geführt. Obwohl ich schon lange mit ASP.NET und JavaScript arbeite, musste ich Atlas von Grund auf neu lernen. Aber das Atlas-Team war sehr offen und hat mir viel Unterstützung geboten, insbe sondere im öffentlichen Forum unter http://jorums.asp.net/dejault.aspx?GroupID=34. Ich bin einem beeindruckenden Team technischer Gutachter dankbar, die mir geholfen haben, dieses Buch zu gestalten, und mir Feedback gegeben haben. In alphabetischer Reihenfolge sind die Personen, die mir mehrfach geholfen haben, meinen guten Ruf zu wahren: Adonis Bitar, Arsen Yeremin, Bertrand Le Roy, Christoph Wille, Mike Pope und Tobias Hauser. Außerdem stehe ich in der Schuld meines Lektors John Osborn, der mich in diesem Pro jekt angeleitet hat. Er ist der einzige Lektor, den ich kenne, der sich jemals beschwert hat, wenn ich Material vor dem ausgehandelten Abgabetermin abgeliefert habe. Aber er war ein exzellenter Projektmanager, der es mir ermöglicht hat, mich auf das Schreiben zu konzentrieren und es in angemessener Zeit zu bewältigen. Schließlich muss ich zugeben, dass ich kein Freund persönlicher Danksagungen an Fami lienmitglieder, Männer/Frauen/Freundinnen/Lebensgefährtinnen oder Katzen/Hunde bin. (Die einzige Ausnahme ist Richard Hundhausen, der einmal seinen Dank dafür aus-
Einleitung I XXI
gedrückt hat, dass es dort, wo er lebt, keine 24-Stunden-Scheidungsdienste gibt.) Aller dings möchte ich die Gelegenheit nutzen, meinen Eltern zu danken. Sie haben mich stark unterstützt, als ich an meinem ersten Buch arbeitete, und jetzt, ungefähr 50 Bücher später, zeige ich endlich etwas Anerkennung. Peinlicherweise finden sie manchmal sogar Fehler, ohne Kenntnis der Technologie zu haben. Also: danke Mama, danke Papa. Und - da ich jetzt einmal dabei bin - danke ich meinen Freunden und meiner Familie, die es nicht zu stören scheint, wenn ich mich zu langen Schreibphasen zurückziehe oder mal wieder unterwegs zu einer weiteren Konferenz bin.
Danksagungen (2. Auflage) Manchmal hat man einfach ein schlechtes Timing. Ungefähr zwei Wochen, nachdem die erste Auflage dieses Buchs, das damals noch Programming Atlas hieß, veröffentlicht wurde, änderte Microsoft den Namen in ASP.NET AJAX. Schlechtes Timing aber nicht nur wegen des neuen Namens: Außer dem Namen hat Microsoft auch die innere Funkti onsweise des Frameworks gravierend verändert. Die Folge war, dass kein Atlas-Code mit ASP.NET AJAX funktionierte. Zugegeben: Bei vielen Anwendungen war die Portierung trivial, aber einige Funktionalitäten wurden entfernt oder irreversibel geändert. Deswegen sieht diese Auflage ganz anders aus als die letzte: Die Struktur wurde vollstän dig umgeworfen, es gibt viele neue Kapitel, es gibt eine Menge neuen Inhalt, einige Inhalte wurden entfernt, einige Kapitel wurden umgeschrieben. Auch wenn das hier technisch betrachtet eine zweite Auflage ist, ist es mehr oder minder ein neues Buch. Ich schulde John Osborn, meinem Lektor, Dank. Er hat das Projekt gesteuert und mir ständig neue Ideen für das Buch gegeben. Mike Pope war der wichtigste technische Rat geber (eine Rolle, die er schon bei der ersten Auflage des Buchs übernommen hat). Er hat nicht nur die meisten meiner Microsoft-Witze entfernt (seufz), sondern mir auch unzäh lige Vorschläge, Kommentare und Ideen für diese neue Auflage zukommen lassen. Es war eine Menge Arbeit, für ihn (das Finden von Problemen) wie für mich (sie zu beheben), aber ich denke, dass das Ergebnis die Mühe wert war. Dank ihnen beiden dafür, dass sie die zweite Auflage noch besser gemacht haben als die erste. Dank auch an alle Leser der vorangegangenen Auflage, die mir Feedback und Vorschläge zukommen ließen. Und Dank auch den verschiedenen Entwicklern, die ich mit Hilfe die ses Buchs unterrichtet habe und die mir ebenfalls Feedback gegeben haben.
XXII I Einleitung
TEIL I
Grundlagen
KAPITEL 1
ASP.NET AJAX, Ajax und ASP.NET
In diesem Buch geht es um ASP.NET AJAX (das in seinen Vorabversionen »Atlas« genannt wurde). ASP .NET AJAX ist der Name für eine Sammlung neuer Microsoft-Tech nologien, die es Webentwicklern, insbesondere ASP.NET 2.0-Entwicklern, ermöglichen, Websites mit Seiten zu erstellen, die Ajax einfacher nutzen. Ajax-artige Seiten bieten Benutzern eine reichere Schnittstelle, sind reaktiver, weil Seiten unmittelbar auf Benut zerinteraktionen reagieren können, und können mehr oder weniger sofort mit dem Ser ver interagieren. ASP .NET AJAX schließt außerdem Werkzeuge zur Erstellung von Mashups ein: Das sind Webanwendungen, die Inhalte von mehreren Seiten kombinieren und dazu üblicherweise APIs verwenden, die von externen Webservices gestellt werden. Wir werden uns all diese Fähigkeiten und mehr in diesem Buch ansehen. Dieses Kapitel sagt Ihnen, wie Sie in ASP .NET AJAX einsteigen, liefert einen Überblick über die beteilig ten Technologien und erklärt aus architektonischer Perspektive, wie ASP.NET AJAX funktioniert.
ASP.NET AJAX und Ajax ASP.NET AJAX beruht auf standardnahen Browsertechnologien einschließlich asynchro nem JavaScript und XML Ajax selbst hat in jüngster Zeit ziemlich Furore gemacht (in der »Einleitung« finden Sie einige Gedanken dazu), da es die Funktionalität und das User Interface (VI) von Webanwendungen denen von Desktop-Anwendungen annähern kann. Der Grundgedanke hinter Ajax ist, Webseiten so aufzubauen, dass sie im Hintergrund oder asynchron HTTP-Anfragen durchführen, ohne die gesamte Seite neu zu laden (bzw., um im ASP.NET-Jargon zu sprechen: einen Roundtrip oder ein Postback durchzufüh ren). Ajax bietet außerdem Mittel, ein reaktionsfähigeres UI zu erstellen, indem die Mög lichkeiten von JavaScript, dem Document Object Model (DOM) des Browsers und CSS ausgenutzt werden, die von den meisten Browsern unterstützt werden. JavaScript wird beispielsweise genutzt, um die Informationen anzuzeigen, die auf eine HTTP-Anfrage zurückgeliefert werden, ohne die Seite vollständig zu aktualisieren. Google Suggest (http://www.goog/e.com/webhp?comp/ete=l &h/=en) zeigt, wie eine Ajax-fähige Seite
I l
Wörter vorschlagen kann, während der Benutzer Text eingibt (was auch als Autovervoll ständigung bezeichnet wird). Eine andere Ajax-artige Anwendung ist die Microsoft Vir tual Earth-Site (http://www.virtualearth.com). Ein Ziel von ASP.NET A]AX ist es, Ihnen zu helfen, derartige Ajax-fähige Anwendungen zu erstellen, indem Sie den Browser (Client) programmieren. Um mit der Clientseite von Ajax und ASP.NET A]AX zu arbeiten, benötigen Sie eine gute Kenntnis der Ajax-Kern technologien. Um Ajax-fähige Webseiten zu programmieren, indem Sie den Browser pro grammieren, müssen Sie ]avaScript und das DOM kennen und müssen mit dem XMLHttpRequest-Objekt vertraut sein, das die Anfragen vom Client an den Server abwi ckelt. (Zusätzliche Kenntnisse in XML und XSLT sind von Vorteil, aber nicht erforder lich. Wir werden sie in diesem Buch nicht viel verwenden.) Während sich Kapitel 2 mit den Grundlagen von ]avaScript befasst, werden Sie die ande ren Ajax-Technologien in Kapitel 3 ausführlicher kennenlernen. Um dem Beispiel in die sem Kapitel zu folgen (siehe weiter unten »Ein erstes ASP.NET A]AX-Beispiel: Hallo Benutzer«), brauchen Sie nur ein elementares Verständnis der Ajax-Technologien, das wir im Folgenden liefern werden. Ohne ein Framework wie ASP.NET A]AX ist das Schreiben Ajax-basierter Anwendungen nicht unbedingt einfach, und möglicherweise werden Sie feststellen, dass Sie immer wie der den gleichen Code schreiben müssen, um Aufgaben wie die Anzeige der vom Server auf eine Anfrage zurückgelieferten Daten, das Binden von Steuerelementen an Daten oder die Arbeit mit Webservices zu bewältigen. Außerdem kann es sein, dass Sie Code schreiben müssen, um Unterschiede in der DOM-Implementierung der unterschiedli chen Browser zu umgehen. Eines der Ziele von ASP.NET A]AX ist das Verringern - wenn nicht sogar das Eliminieren - der Notwendigkeit, solchen Code schreiben zu müssen, sowie die Entwicklung auf der Clientseite der Entwicklung unter ASP.NET 2.0 anzuglei chen. Ein damit verknüpftes Ziel ist es, ]avaScript einen Teil der Produktionsvorteile der objektorientierten Programmierung (OOP) und eines Frameworks wie .NET mitzuge ben. Deswegen enthält ASP.NET AJAX Clientskriptbibliotheken, die JavaScript/DOM/ CSS-Programmierern Folgendes bieten:
Browser-Kompatibilitätsschicht Sie ermöglicht es, ASP.NET A]AX-Skripten in den meisten Browsern auszuführen, und entbindet den Programmierer von der Notwendigkeit, Skripten speziell für jeden Browser zuzuschneiden, in dem eine Seite verwendet werden können solL (Aber wie Sie in Kapitel 3 sehen werden, sind einige browserspezifische Skriptele mente unvermeidbar.)
Kerndienste Die Kerndienste bieten ]avaScript-Erweiterungen, die OOP-artiges Skripting ermöglichen und Unterstützung für Klassen, Namensräume, Event-Handling, Ver erbung und die Objektserialisierung mit den Formaten ]SON OavaScript Object Notation) und XML Die wertvollsten dieser Erweiterungen werden in Kapitel 4 behandelt.
4 I Kapitel l: ASP.NETAJAX,AjaxundASP.NET
Basis-Klassenbibliothek Die Basis-Klassenbibliothek bietet eine Reihe von .NET-artigen Komponenten wie String-Builder und Timer. Die StringBuilder-Klasse von ASP.NET AJAX werden Sie in Kapitel 4 kennenlernen.
Skript-Steuerelemente und -Komponenten Diese bieten ASP.NET AJAX-Versionen der Standard-HTML-Steuerelemente, die um Fähigkeiten wie Datenbindung, vorgefertigte Verhalten (beispielweise Drag-and Drop-Funktionalitäten) und eine enge Integration mit den ASP .NET AJAX-Client bibliotheken erweitert wurden. Sie können diese Steuerelernente und Komponenten direkt programmieren, oder Sie können ein neues deklaratives Markup namens xml script verwenden, auf das Sie in mehreren Kapiteln stoßen werden. Wenn Sie mit der ASP.NET-Markup-Syntax vertraut sind, verstehen Sie (in allgemeinen Begriffen) bereits, welche Beziehung HTML-Steuerelemente, abstrakte programmierbare Ver sionen dieser Steuerelemente und eine deklarative Syntax haben.
ASP.NET AJAX und ASP.NET Auch wenn ASP.NET AJAX Programmierern von Clientskripten, die Ajax-Anwendungen erstellen, viele Vorteile bringt, geht es bei ASP .NET AJAX nicht nur darum, JavaScript zu schreiben und asynchrone Aufrufe an den Server durchzuführen. Da ASP.NET AJAX vom ASP .NET-Team geschaffen wurde, ist es keine Überraschung, dass ein herausragen des ASP.NET AJAX-Feature ein Server-Framework ist, das in ASP.NET 2.0 integriert ist (und es erfordert). Wie bei ASP.NET selbst ist es eines der Ziele von ASP.NET AJAX, Funktionalitäten - in diesem Fall die Vorteile von Ajax - zu liefern, ohne dass man dazu die Technologien beherrschen muss, die dafür sorgen, dass sie funktionieren. ASP.NET AJAX kann Ajax Funktionalitäten auf ziemlich die gleiche Weise für Sie steuern, wie ASP.NET HTTP Funktionalitäten wie Postbacks, Zustandsverwaltung und das Clientskript steuern kann, das erforderlich ist, damit ASP.NET »einfach funktioniert« . Daneben arbeitete ASP.NET AJAX auf der Serverseite als Teil von ASP.NET und kann die ASP .NET-Features nutzen. ASP .NET AJAX-Steuerelemente können mit ASP .NET-Steuer elementen und -Komponenten und dem Lebenszyklus von Seiten interagieren. Sie können ASP.NET AJAX mit ASP.NET 2.0-Features wie Sessions, Authentifikation und Profilen verknüpfen, um die Vorteile dieser Arten von Fähigkeiten auf den Client zu bringen. Außerdem können Sie mit ASP.NET AJAX und ASP.NET über die Seite hinaus auf spe zielle Webservices zugreifen. Zu den Schlüsselelementen des ASP.NET AJAX-Server-Frameworks zählen:
ASP.NET AJAX-Serversteuerelemente Die ASP-NET AJAX-Serversteuerelemente bieten serverbasierte Steuerelernente, die den ASP.NET 2.0-Serversteuerelementen ähneln, aber mit dem ASP.NET AJAX Client-Framework zusammenarbeiten, um ihre Funktionalität bereitzustellen. Zwei
ASP.NETAJAXundASP.NET I 5
Steuerelemente sind für ASP.NET AJAX-Anwendungen besonders essenziell: ScriptManager, das weiter unten in diesem Kapitel betrachtet wird (siehe »Das ScriptManager-Steuereiement«), und UpdatePanel, das in Kapitel 6 behandelt wird.
ASP.NET AJAX ASP.NET-Dienste Diese Dienste bieten bestimmte ASP.NET 2.0-Anwendungsdienste, die ASP.NET AJAX-Clientskripten direkt zur Verfügung stehen, einschließlich profil-, personali sierungs-, authentifizierungs-, mitgliedschafts- und länderspezifischen Diensten. Sie können davon ausgehen, dass die Anzahl der ASP.NET-Dienste, die ASP.NET AJAX-Anwendungen zur Verfügung stehen, mit zukünftigen Versionen von ASP.NET AJAX wachsen wird.
Die Microsoft Ajax Librory Diese Library bietet eine reineJavaScript-Bibliothek, die nicht von ASP .NET abhängig ist, und kann deswegen ohne ASP.NET eingesetzt werden. Dies wird in Kapitel 22 gezeigt. Am Ende wird ASP.NET AJAX seinen angestammten Platz als Schlüsselkomponente der nächsten Version von ASP.NET einnehmen und vollständig von Designern, IntelliSense und den Debugging-Tools in zukünftigen Versionen von Visual Studio unterstützt wer den.
ASP.NET AJAX-Pakete Auf der ASP.NET AJAX-Homepage unter http://ojax.asp.net/ werden Sie auf mehrere separate Pakete stoßen, die jeweils ihren besonderen Zweck haben:
ASP.NET AJAX Extensions Das ist das »Haupt«-ASP.NET AJAX-Paket, das gelegentlich auch als »ASP.NET AJAX Core« bezeichnet wird. Dieses Paket wird von Microsoft vollständig unter stützt und enthält die ASP.NET AJAX-Infrastruktur (und wird in Teil II dieses Buchs behandelt).
ASP.NET AJAX Control Toolkit Dieses Paket enthält eine umfangreiche Sammlung serverseitiger Komponenten, die mit sehr wenig Arbeit überraschende Ajax-Funktionalitäten bieten. Dieses Projekt ist ein Open-Source-Unternehmen. Allerdings wird es weiterhin von Microsoft gesteuert, um die Qualität zu sichern. Es gibt allerdings keine offizielle Microsoft Unterstützung für die Teile des Toolkits. Teil III dieses Buchs wird sich mit dem Control Toolkit befassen.
ASP.NET AJAX Futures Release Dieses Paket bietet einen Ausblick auf zukünftige Features, die zu Teilen von ASP.NET und ASP.NET AJAX werden könnten (oder auch nicht). Das Future-Paket ist außerdem die Heimat weniger häufig verwendeter Funktionalitäten, die ursprünglich Teil der Vorabversionen von ASP.NET AJAX waren. Das CTP wird häufiger aktualisiert als das Kernpaket. Offiziell wird es allerdings nicht unterstützt.
6 I Kapitel l: ASP.NETAJAX,AjaxundASP.NET
Sie setzen es also auf eigenes Risiko ein. Teil IV dieses Buchs behandelt das Futures Paket in der aktuellen Version zum Zeitpunkt der Drucklegung dieses Buchs, d.h. die ASP.NET Futures-Version vom Juli 2007. Seit Mai 2007 ist das ASP.NET AJAX Futures CfP außerdem Teil des ASP .NET Futures CTP, das faszinierende neue (und nicht unterstützte) Möglichkeiten für klassisches ASP.NET bietet.
Die Microsoft Ajax Library Die bereits erwähnte reine JavaScript-Bibliothek, die in Teil V behandelt wird. .. .
In einem etwas überraschenden Zug hat Microsoft den vollständigen Quellcode für ASP.NET AJAX veröffendicht. Er kann ebenfalls von �: http://ajax.asp.neUheruncergeladen werden.
[TI ,: �:' ,� ,
,
.
Dieses Kapitel befasst sich zunächst mit den Kern-ASP.NET AJAX-Erweiterungen (und geht auch kurz auf das Futures CTP ein). Die anderen Pakete werden zu Anfang der jeweiligen Kapitel des Buchs richtig vorgestellt.
ASP N ET AJAX Erfordernisse und Installation .
-
-
Die beste Möglichkeit, um zu verstehen, wie mächtig ASP.NET AJAX ist, ist die eigentli che Arbeit mit ASP.NET AJAX. Alles, was Sie benötigen, um ASP.NET AJAX-Anwen dungen zu entwickeln, ist ein JavaScript-fähiger Browser auf der Clientseite und ein ASP.NET 2.0-fähiger Webserver auf der Serverseite. Ein Texteditor reicht aus, um ASP.NET AJAX-Anwendungen zu erstellen. Aber insbesondere wenn Anwendungen komplexer werden, kann eine IDE mit zusätzlichen Features wie IntelliSense, Codever vollständigung, Projektverwaltung, Debugging und WYSIWYG-Funktionalitäten eine Menge Zeit sparen. Den in der ASP.NET 2.0-Welt am meisten verwendeten Editor liefert Microsoft in der Form von Visual Studio 2005.
Die IDE installieren Die gute Nachricht ist, dass, auch wenn die vollständigen Versionen von Visual Studio 2005 in der Regel die beste Wahl sind, die weborientierte Express-Ausgabe von Visual Studio 2005 - Microsoft Visual Web Developer 2005 Express Edition - ebenfalls voll ständige ASP.NET AJAX-Unterstützung bietet. .. .
Der Einfachheit halber werden wir Visual Web Developer in diesem Buch gelegendich mit VWD abkürzen. Mit VWD meinen wir die Express-Aus �' gabe und die vollständige Version von Visual Studio 2005 gleichermaßen. . Die Webencwicklungskomponence von VS 2005 wird ebenfalls als Visual Web Developer bezeichnet (wie Sie während der Installation von Visual Studio sehen können), VWD ist also der allgemeinste Begriff für die Erstel lung von ASP.NET 2.0-Anwendungen mit einer Microsoft-IDE.
[TI ,: '!..' :'' .
ASP.HEl AJAX-Erfordernisse und -Installation I 7
Wenn Sie noch keine IDE installiert haben, sollten Sie entweder Visual Studio 2005 oder Visual Web Developer Express Edition installieren. Letztere finden Sie unter hup://www.microso[t.com/germony/msdnlvstudio/products/express/downlood.mspx. Dort finden Sie einen Web-Installer, der nicht nur VWD installiert und herunterlädt (den Installer sehen Sie in Abbildung 1-1), sondern sich auch darum kümmert, das .NET Framework 2.0 zu installieren, wenn es auf Ihrem System noch nicht installiert ist. Befol gen Sie die Anleitungen auf der Seite . . ",
Sie können aufder gleichen Seite gegen eine Gebühr eine DVD bestellen, die alle deutschen Visual Studio Express-Versionen und Installationsvoraus �' setzungen enthält. Alternativ finden Sie unter http://www.microsojt.com/ . germany/msdn/vstudio/products/express/manuelleinstallation.mspx ISO- und IMG-Images für eine CD, die die deutsche Version von Visual Web Developer und alle Voraussetzungen enthält. Diese können Sie irgendwo herunterladen, wo Sie eine bessere Verbindung haben, und dann auf eine CD brennen.
Gil " �:' �.'
Ziel ord ner
W1ihlen Sie den Speicherort
ilUS, iln dem Visuill Web Developer 2005 Express
Edition iMtillliert werden soll.
In foh;Jendem Ordner rnt�eren: [{O\PrOQrilmme\Microsoft VisUili studio 8\
[Qurchsuchen ..I
Die folQenden Produkte werden Qedownloildet und instilliiert: •
il
Visu l Web Developer 2005 Express Edition
40 MB
Erforderlicher Festplilttenspeicher:
.D
DOl'lnloildQröße Qesilmt:
C: 420 MB
steRen Sie eine \lerbirKllslQ mit dem Internet her, bevor Sie die In5tillliltion fortsetzen.
., Zurück I UnstilIlieren :" I [ Abbrechen '
Abbildung 1-1: Die Visual Web Developer Express Edition installieren
ASP.NET AJAX installieren Egal welche VWD-Version Sie einsetzen, ASP.NET AJAX ist direkt in die IDE integriert. Auf der ASP.NET AJAX-Homepage (hup://ojox.asp.net! finden Sie ASP.NET AJAX in Form eines MSI-Installer-Pakets namens ASPAJAXExtSetup.msi. Die ASP.NET AJAX8 I Kapitel l: ASP.NETAJAX,AjaxundASP.NET
Webseite bietet einen gut sichtbaren Link zu diesem Paket. Suchen Sie nach Microsoft
ASP.NET 2.0 AJAX Extensions 1.0. Falls sich bereits ältere Versionen von ASP.NET AJAX auf Ihrem System befinden soll ten, deinstallieren Sie alle alten ASP.NET AJAX-Versionen, bevor Sie den Installer star ten. Der .msi-Installer stellt nicht zu viele Fragen. Sie müssen die Lizenz für ASP.NET AJAX akzeptieren. Dann startet die Installation, wie Sie es in Abbildung 1-2 sehen. 181 Microsoft ASP.NET 2.0 AJAX Extensions 1.0 Setup
�:JC �
Installino Microsoft ASP.NIT 2.0 AJAX Extensions 1.0
PIe�se Will! M1iIe the Setup WiZMd inst.5ls MIcrosoft �./'ET 2.0 AJAX Extensions 1.0.
Status:
[........................................... .
Abbildung 1-2: Die Vorlage installieren Nach einer erfolgreichen Installation haben Sie in VWD und Visual Studio eine neue Option, wenn Sie eine Website erstellen: ASP.NET AJAX Web Sire. Das ist die einfachste Möglichkeit, in die ASP.NET AJAX-Technologie einzusteigen, da so alle erforderlichen ASP.NET AJAX-Dateien kopiert und in die richtigen Verzeichnisse gesteckt werden (siehe Abbildung 1-3) und die ASP.NET AJAX-Assembly im GAC (Global Assembly Cache) installiert wird, damit sie automatisch für alle ASP.NET-Anwendungen zur Ver fügung steht. Visual Studio 2008 und Visual Web Developer 2008 Edition funktionieren übrigens auch mit ASP.NET AJAX. Wenn Sie beim Erstellen einer neuen Website angeben, dass das .NET Framework 3.5 verwendet werden soll (siehe Abbildung 1-4), müssen Sie ASP.NET AJAX nicht einmal installieren, denn es wird mit dem .NET Framework 3.5 mitgeliefert (und ist somit auch in der Vorlage ASP.NET Web Site enthalten) . Für .NET-Versionen vor 3.5 benötigen Sie ASP.NET AJAX weiterhin. Sollten Sie mit Visual Studio 2005 und mit Visual Studio 2008 arbeiten oder in Visual Studio 2008 ASP.NET-AJAX-Projekte öff nen, die mit Visual Studio 2005 erstellt worden sind, beachten Sie unbedingt die Hin weise im Abschnitt »Zum weiteren Lesen« am Kapitelende.
ASP.HEl AJAX-Erfordernisse und -Installation I 9
Neue Webslte
rnrgJ
Von Visual 5tudio instal1i�rt� Vorlag�n
� ASP.NET·Webdienst
",,'Starter Klt fis pers6riche Websites
ttJASR.NET AJAX CTP.enabI�d Web .. \\Leer� W�bSlte
M�in� Voriag�n
I [ -""'"
OK
Abbildung 1-3: Nach der Installation haben Sie eine neue Website-Vorlage.
L1I�
New Web Sile
Templates: 11
�ASP.t>ET Web Ste l.:'tDynamtc: DM� W�b Site .... 1ASP.t>ET Futoses AJAX web Sie .... "ASP.NET Futoses Web Sie �A5P ,!\ET Cry..t Jg, "> ; " ) . replace(J"Jg, "" ; " ) . replace(J'Jg, "'" ); return result ;
}
docurnent.write(HtrnlEscape (" ")); Wenn es ausgeführt ist, gibt Beispiel 2-7 aus. Im Browser wird das als ausgegeben, erzeugt aber keinen horizontalen Trennstrich. JavaScript bietet keine Unterstützung für das Überladen von Funktionen. Allerdings ist die Anzahl der Argumente in einer Funktion nicht fixiert. Wenn in der Funktionssignatur mehr Argumente vorgegeben sind, als vom Aufrufer übergeben werden, wird den zusätz lichen Argumenten der Wert null zugewiesen.
32 I Kapitel 2: JavaScript
Andererseits liefert die Eigenschaft arguments (die Kurzform für .argu ments) Zugriff auf alle überschüssigen Argumente, wenn mehr Argumente angegeben werden als erwartet. Das zeigt Beispiel 2-8. BeispieI 2·S: Eine benutzerdefinierte Funktion mit einer variablen Anzahl von Argumenten schreiben
JavaScript-function·argurnents.htrn < ! OOCTYPE htrnl PUBLIC "./ /W3C1IDTD XHTML 1.0 Transitional/ /EN" ''http://1rMW . w3. org/TR/xhtrnll/DTD/xhtrnll-transitional. dtd" > JavaScript function Book(isbn, author, title) { var _isbn = isbn; var _author = author; var _title = title; this.get_isbn = function() { return _isbn;
}
this. set isbn = function(value) { Isbn = value;
}
this.get_author = functionO { return _author;
}
this. set author = function(value) { _author = value;
}
this.get_title = functionO { return _title;
}
this. set title = function(value) { title = value;
Beispiel 2-10: MitjavaScript Vererbung nutzen (Fortsetzung)
}
}
"
-
"
+
this.get_sizeO
DigitalBook.prototype
=
+
" KB";
new Book(); IIVon Book abzuleitende Klasse
var atlas = new DigitalBook("0123456789", "International Graphics", "Atlas of the City"); atlas . set_size( 1024) ; document.write(atlas.toString()); Abbildung 2-5 zeigt das Ergebnis, das angezeigt wird, wenn Beispiel 2-10 ausgeführt wird. " JavaScript Mozilla firefox -
�§rg) J� •
•
International Graphics: Atlas 01the City (0123455789) - t024 KB
Abbildung 2-5: Die toStringO-Methode des abgeleiteten Objekts
Auf Seiten elemente zugreifen Obwohl neue Browser das W3C DOM als Mittel für den Zugriff auf Elemente der aktuel len HTML-Seite unterstützen (mehr Informationen finden Sie im Abschnitt »DOM Methoden« weiter unten in diesem Kapitel), gibt es, wie Sie später sehen werden, einfa chere Wege, mit den Daten auf einer Seite zu arbeiten. Zwei davon werden in diesem Abschnitt behandelt.
Auf Formularelemente zugreifen JavaScripts d oc ument-Objekt bietet Zugriff auf alle Elemente der aktuellen Seite. document ist eine Repräsentation des DOM, auf die von JavaScript zugegriffen werden kann. Um den Zugriff so bequem wie möglich zu machen, gibt es verschiedene Untereigenschaften, die den direkten Zugriff auf besondere Seitenelemente ermöglichen. Hier sind einige Bei spiele in alphabetischer Reihenfolge:
document . embeds Ein Array, das alle (über Der Ausdruck document . forms [ 0] . e1ement s [ "TextBoxl" ] greift auf das Formularelement namens TextBoxl im ersten Formular der Seite zu. (Eine Kurzform dafür ist docu ment. forms [0] . TextBoxl; das funktioniert allerdings nicht, wenn im name-Attribut des For mularelements Sonderzeichen - wie Leerzeichen oder Bindestriche - verwendet werden.) Je nachdem, welchen Typ das Formularelement hat (z.B. Textfeld, Radiobutton, Auswahlfeld), gibt es kleine Unterschiede beim Zugriff auf den Wert, aber in der Regel enthält das va1ue-Attribut diese Informationen, genau wie das HTML-Attribut va1ue für die meisten Formularfelder. Beispiel 2-11 gibt, sobald der Benutzer auf einen Button klickt, die Daten aus, die in ein Textfeld eingegeben wurden. Das Markup für den Button sieht folgendermaßen aus:
Wenn Sie auf den Button klicken, wird die Funktion ShowText( ) aufgerufen. Der Parame ter ist this. form, eine Referenz auf das Elternformular des Elements. Das macht es etwas einfacher, auf die Daten zuzugreifen, weil Sie in der aufgerufenen Funktion nicht mehr document. forms [0] verwenden müssen. Beispiel 2-11 zeigt den vollständigen Code. Beispiel 2-1 1 : Auf Formularelemente zugreifen
JavaScript-form-textbox.htm < ! OOCTYPE html PUBLIC "-IIW3C1fDTO XHTML 1.0 Transitionall/EN" ''http://1rMW . w3. orgfTR/xhtmll/DTOfxhtmll-transitional. dtd" > JavaScript
AufSeitenelemente zugreifen I 39
Beispiel 2-11: Auf Formularelemente zugreifen (Fortsetzung)
function ShowText(f) { alert("Eingegebener Text: f.elements["TextBoxl" ] . value); "
+
)
Abbildung 2-6 stellt das Ergebnis nach Ausführung dieses Skripts dar.
[
T�!lnZ� Oie Seite mit der Adresse l.J
http;/llocalhost:33...
�
Eilge9� T�xt: Fnt2
OK
Abbildung 2-6: Die Formulardaten werden im Dialogfenster gezeigt. Tabelle 2-1 zeigt die Eigenschaften, die für den Zugriff auf die am häufigsten verwende ten Werte in den am häufigsten verwendeten Formularfeldtypen genutzt werden. Bei spielsweise kann auf den Wert in einem Textfeld, das mit dem Markup definiert wurde, mit dem Ausdruck document. forms [0] . elements [ "Name"] . value zugegriffen werden (vorausgesetzt, das entsprechende Textfeld wurde im ersten oder einzigen Formular des Dokuments definiert). Tabelle 2-1 : HTML-Formularfelder und die entsprechenden Eigenschaften Fonnularfeld
HTML-Markup
Textfelder und Passwortfelder
Radiobuttons
40 I Kapitel 2: JavaScript
Eigensc:haft
value: ruft die Daten im Feld ab und setztsie checked: gibt an, ob der Radiobutton ausgewählt ist oder nicht
Tabelle 2-1 : HTML-Formularfelder und die entsprechenden Eigenschaften (Fortsetzung) Eigensc:haft checked: gibt an, ob die Checkbox ausgewählt ist oder nicht
Fonnularfeld Checkbox
HTML-Markup
Auswahllisten
selectedIndex: der Index des ersten aus gewählten Elements (oder -1, wenn kein Element ausgewählt ist) options: ein Array, das alle Listenoptionen enthält
Auswahllistenoption
selected: gibt an, ob eine Option ausgewählt ist oder nicht va 1 ue: der Wert einer OptionFormu larelemente, Zugriff auf
Zugriff auf allgemeine Elemente document. forms ist sehr praktisch, um Formulardaten zu lesen. Eines der Hauptszenarien für JavaScript - insbesondere wenn es als Teil einer Ajax-Implementierung genutzt wird - ist die Anzeige von Daten, beispielsweise in einem Absatz « p» oder einem Textbereich « span> oder < labe!» . Das können Sie in drei Schritten durchführen: 1. Sie verwenden das name-Attribut, um einen eindeutigen Bezeichner für den Absatz oder den Textbereich anzugeben. Der Bezeichner ist für die HTTP-Anfrage nicht erforderlich und wird nicht verwendet, wenn das Formular abgeschickt wird. Er wird aber oft eingesetzt, um mit JavaScript auf Elementwerte zuzugreifen.
2. Sie verschaffen sich in JavaScript eine Referenz auf das Element, indem Sie den Aus druck document .getE1ementByld( ) verwenden. 3. Sie setzen die innerHTML-Eigenschaft des Elements, um die Daten im Element anzuzeigen. Beispiel 2-12 nimmt erneut die Daten aus einem Textfeld, schreibt sie dieses Mal aber in ein -Element. Beispiel 2-12: HTML und Text in ein Element schreiben
Eine vollständige Referenz der Eigenschaften und Methoden des XMLHtt pRequest-Objekts finden Sie in Anhang A.
--
Ein Wort zur Sicherheit: Per Default kann XMLHttpRequest nur auf Ressourcen zugreifen, die sich in der gleichen Domain befinden wie das Clientskript. Unglücklicherweise schränkt das die Fähigkeiten der Technologie ein, da es keine einfache Möglichkeit gibt, über Ajax einen Webservice aufzurufen. Mozilla-Browser ermöglichen den Zugriff auf Remote-Server in einer anderen Domain, indem sie beim Benutzer explizit zusätzliche Berechtigungen anfordern. Abbildung 3-5 zeigt die Nachricht, die den Benutzer zur Bestätigung auffordert. Allerdings erzeugt dieses Verfahren eigene Probleme und ist nicht browserübergreifend. Das ist der Grund dafür, dass es heutzutage selten verwendet und in diesem Buch nicht beschrieben wird. Alle HTTP-Anfragen, die in diesem Buch gezeigt werden, richten sich also an den Server, von dem die Seite selbst stammt.
Das XMLDocument-Objekt Die responseXML-Eigenschaft des XMLHttpRequest-Objekts erwartet, dass der Rückgabe wert des entfernten Aufrufs die Form eines XMLDocument-Objekts hat. Das erfordert, dass der Servercode wohlgeformte XML-Daten zurückliefert, damit das Clientskript sie parsen kann. Es ist allerdings leicht, auf diese XML-Daten zuzugreifen, weil Ihnen die vollstän dige DOM-Unterstützung zur Verfügung steht.
S6 I Kapitel 3: Ajax
3
�
=
""'"" "'.e Internet-Sicherheit
Ei'1 �tvon "fie:/r erbttet Sonderred1te, ce � snd lrod beruut "''erden kDmten, o..m Ihren CO!rputer oder rlYe Daten zu kompromittieren.
rg)
Ver� � ce SonderrfitlN' ru, W� 5.le: SICher snd, dMs eil! Q.Jeh � Vren oder � Prograornme entMIt.
o DIese Entsdledn;l merken
r[;= """," , 1 [-;;";;;;j
Abbildung 3-5: In einem Mozilla-Browser zusätzliche Berechtigungen anfordern JavaScript unterstützt eine Reihe von DOM-Features für den Zugriff auf bestimmte Kno ten in der XML-Datei oder für die Navigation in der Baumstruktur des XML-Dokuments. Anhang B enthält eine vollständige Liste der Methoden und Eigenschaften des XMLDocu ment-Objekts. Das folgende Beispiel zeigt, wie man einige davon verwendet. Stellen Sie sich vor, dass die folgenden XML-Daten die Rückgabedaten der Serverantwort darstellen:
ASP.NET AJAX function pageLoad() { var s = Type. registerNamespace ("OReilly"); OReilly.Software = function(name, vendor) { var _name = (name != null) ? name : "unknown"; var _vendor = (vendor ! = null) ? vendor : "unknown"; this.getName = function() { ASP.HEl AJAX-QOP-Features für JavaSaipt I 7S
Beispiel 4-1 : ASP.NET AJAX-Namensräume einsetzen (Fortsetzung)
Type .registerClass( "OReilly. Software" ) ; var ie = new OReilly.Software("Internet Explorer", "Microsoft")j s = ie.getNameO + " von " + ie.getVendorO + ""j var ff = new OReilly.Software()j ff.setName("Firefox" ) j ff .setVendor("Mozilla Foundation") j s += ff.getNameO + " von " + ff.getvendorO j
document. getElementById ("output") . innerHTML = s ; } Abbildung 4-1 zeigt das Ergebnis, wenn die Seite geladen ist. Auch wenn die Namensraumklassen von ASP.NET AJAX keine »echten« Namensräume sind, können sie es Ihnen leichter machen, komplexen JavaScript-Code zu struktu rieren, und benötigen dazu nur wenig zusätzlichen Code.
Klassenvererbung In JavaScript gibt es eine beschränkte Unterstützung für Klassenvererbung in Form der prototype-Eigenschaft, die in Kapitel 2 erläutert wurde. ASP.NET AJAX bietet eine wei tere Abstraktionsschicht. Der prototype-Mechanismus wird für Namensraumklassen unterstützt, die mit Klasse.registerClass( ) registriert wurden. Als zweiten Parameter
76 I Kapitel 4: Die ASP.NET AJAX-JavaScript-Erweiterung verwenden
t:) ASP.NU IUAX · Mozilla Firefox
rJ§�
+ . Inlernet Explorer von r.1icroson Fireloxvon r,lolilla Foundalion
Abbildung 4-1: Zwei Objekte im gleichen Namensraum instanziieren für registerClass ( ) können Sie eine Basisklasse angeben. Das ist der Ort, an dem Sie sagen, von welcher Klasse die aktuelle Klasse abgeleitet ist. Abgeleitete Klassen
Erzeugen wir eine Klasse, die von Software abgeleitet ist. Eine ganz besondere Art von Software ist ein Webbrowser - erzeugen wir also eine Klasse Browser. Neben den Fea tures der generischen Klasse Software wären bei einem Browser ein paar zusätzliche Eigenschaften hilfreich. Eine i sJ avaS criptSu pporte d-Eigenschaft kann Informationen dazu liefern, ob ein bestimmter Browser in der Lage ist, JavaScript auszuführen:
OReilly.Browser // . . . }
=
function(name, vendor, isJavaScriptSupported) {
Auf folgende Weise würde die Klasse registriert. Beachten Sie, wie die neue Klasse (der String-Parameter) von der alten Klasse OReilly. Software (kein Stringl) abgeleitet wird:
OReilly . Browser .registerClass("OReilly .Browser" , OReilly. Software) ; Natürlich wäre es möglich, wieder Getter- und Setter-Methoden für name und vendor zu erstellen und ebenso den Konstruktorcode zu schreiben. Aber einer der Vorteile (eigentlich der Hauptvorteil) der Klassenvererbung ist, dass Sie Funktionalitäten wieder verwenden können. Da OReilly. Browser von OReilly. Software erbt, können Sie die Get ter- und Setter-Methoden verwenden, die bereits da sind. Allerdings haben abgeleitete Klassen keinen direkten Zugriff auf die in der Basisklasse definierten »privaten« Mem ber. Die in der Konstruktorfunktion definierten »privaten Member« können nur als normale funktionslokale Variablen implementiert werden und sind als solche nur in dem Code der definierenden Funktion zugreifbar. Stattdessen müssen in OReilly.Soft ware (in allen abgeleiteten Klassen) wie in jedem anderen externen Code die öffentli chen Member, in diesem Fall die Getter- und Setter-Methoden, von OReilly verwendet werden, um auf die Daten zuzugreifen. Außerdem müssen Sie die Getter- und Setter-
ASP.HEl AJAX-QOP-Features für JavaSaipt I 77
Methoden und die privaten Member für die neue Eigenschaft isJavaScriptSupported hinzufügen, wie es hier gezeigt wird:
Jetzt müssen wir nur noch den Konstruktor schreiben. Aber anstatt ihn wieder von Grund auf neu zu schreiben, können wir den Konstruktor der Basisklasse wiederver wenden. Dazu bietet ASP.NET AJAX die Methode initializeBase( ) . Der erste Parame ter ist die Instanz, von der die Basisklasse initialisiert wird. Für diese geben Sie in der Regel den Wert this an. Der zweite Parameter ist ein Array mit Argumenten, die dem Basiskonstruktor übergeben werden sollen (der Basiskonstruktor definiert, welche Argu mente er erwartet). In unserem Fall besteht dieses Array aus dem Namen und dem Her steller des Browsers:
OReilly.Browser. initializeBase(this, new Array(name, vendor» ; Sie können ein paar Zeichen sparen und JSON zur Erstellung des Arrays nutzen: OReilly. Browser . ini tializeBase(this, [name, vendor J ) ; Beispiel 4-2 zeigt den Code, den Sie benötigen, um die neue, abgeleitete Klasse Browser zu erzeugen und zu nutzen. Beispiel 4-2: ASP.NET AJAX-Klassenvererbung nutzen
Clientlnheritance.aspx < ! DOCTYPE html PUBLIC "-IIW3CJ/DTD XHTML 1.0 TransitionalJ/EN" ''http://www. w3. org/TR/xhtmll/DTD/xhtmll-transitional. dtd" > [WebMethod] [System.Web.Script. Services.ScriptMethod] public static float DivideNumbers(int a, int b) { if {b oo O} { throw new DivideByZeroException(); } else { return (float)a / b; )
}
Seitenmethoden I 97
Beispiel 5-3: Webservicecode und ASP.NET AJAX-Code gemeinsam in einer Datei (Fortsetzung)
Abbildung 5-2: Eine Datei, ein Webservice, eine Divisionsoperation
Sitzungszustände verwalten Webservices werden manchmal mit dem Argument kritisiert, dass sie eine tolle Techno logie sind, die aber nichts mit dem Web selbst zu tun hat. Da .NET-Webservices (natür lich) nahtlos in ASP.NET integriert sind, können Sie, wenn Sie ASP.NET nutzen, allerdings Szenarien ermöglichen, die die Webservice-Technologie an sich nicht bieten kann. Mit .NET-Webservices können Sie beispielsweise Sitzungszustände verwalten. Und selbst wenn Sie Ajax verwenden, sind diese Sitzungszustände für Sie immer noch aus Ihrer ASP.NET AJAX-Anwendung heraus verfügbar. Das würde es mehreren Ajax Anwendungen auf einem Server beispielsweise ermöglichen, Informationen vom gleichen Benutzer zu teilen. Das zu implementieren ist einfacher, als es zu beschreiben. Die EnableSession-Eigen schaft des [WebMet ho d]-Anributs erledigt die ganze Arbeit - genau so, als würden Sie eine .NET-Webmethode schreiben:
[WebMethod(EnableSession=true) ] Dann können Sie direkt auf das Session-Objekt von ASP.NET zugreifen und Daten hi neinschreiben oder Daten aus ihm lesen. Da die Webmethode statisch sein muss, müssen Sie HttpContext .Current. Session verwenden. Session allein reicht nicht aus, da diese nur tatsächlichen Instanzen der Klasse Page zur Verfügung steht.
Sitzungszurtände verwahen
I 99
Das folgende Codefragment zeigt den Code für zwei Funktionen: Die eine speichert die aktuelle Uhrzeit in einer Sitzung, und die zweite ermittelt den Unterschied zwischen der aktuellen Uhrzeit und dem Zeitstempel in der Sitzung. Wenn es in der Sitzung keinen Zeitstempel gibt, wird - 1 zurückgeliefert.
[WebMethod(EnableSession = true ) ] [System.Web.Script. Services. ScriptMethod] public static double CalculateDifference() { if (HttpContext.Current.Session[ "PageLoaded" ] == null) { return -1; } else { DateTime then = (DateTime)HttpContext. Current . Session[ "Pageloaded" ] ; TimeSpan diff = DateTime.Now. Subtract(then); return diff.TotaISeconds; } } Kehren wir jetzt zu unserer Anwendung zurück, die zwei Zahlen dividieren kann. Wenn die Seite mit dem Code aus dem vorigen Fragment geladen und die Methode SaveTime( ) aufgerufen wird, wird die aktuelle Zeit im Sitzungszustand gespeichert. Wird nun die Division der beiden eingegebenen Zahlen durchgeführt, wird der Zeitunterschied berech net. So kann ermittelt werden, wie lange ein Benutzer das Formular geöffnet hatte, bevor die Division angefordert wurde (was natürlich auch mit einfachem JavaScript gemacht werden könnte, aber zu Demonstrationszwecken nutzen wir hier den Umweg über den Server). Der folgende JavaScript-Code ruft die Webservice-Methode zur Speicherung der Uhrzeit auf, wenn die Seite zum ersten Mal geladen wird, indem die Methode SaveTime( ) auf gerufen wird. Weil wir keinen Rückgabewert brauchen, können wir als Callback eine Funktion angeben, die nichts tut.
function pageLoad(){ PageMethods. SaveTime(doNothing, doNothing); } function doNothing(result) { Ilmacht nichts - ) } :
Wie zuvor brauchen Sie eine callService( )-Methode, um die Webservice-Methode CalculateDifference( ) aufzurufen. Der folgende Code macht zwei Aufrufe von Webser vice-Methoden. Der erste berechnet den Zeitunterschied zwischen dem Zeitpunkt, zu
100 I Kapitel $: Webservic@s
dem die Seite ursprünglich geladen wurde, und der aktuellen Uhrzeit, und der zweite führt die gleiche mathematische Berechnung durch wie zuvor.
PageMethods.DivideNumbers( parseInt (f. elements [" a " ] . value), parseInt (f. elements ["b" ] . value), callComplete, callError); } Schließlich benötigen Sie noch etwas Markup zur Anzeige des Zeitunterschieds. Wir werden den -Container mit der ID output verwenden. Beachten Sie, dass der Rück gabewert -1 von der Webmethode bedeutet, dass in der Sitzung kein Zeitstempel gespei chert war und dass es deswegen keinen anzeigbaren Zeitunterschied gibt:
function showDifference(result) { if (result ! = -1) { document.getElementById( "output" ) . innerHTML = "Das Formular ist seit " + result " Sekunden geöffnet . " ; } } +
Beispiel 5-4 zeigt den vollständigen Markup- und Skriptcode, der für dieses Beispiel im plementiert werden muss. Die Änderungen werden fett dargestellt. Beachten Sie, dass Sie das EnablePageMethods-Attribut des ScriptManager-Steuerelements auch hier wieder auf true setzen müssen, da die Seitenmethoden sonst nicht funktionieren. Beispiel 5-4: Einen Sitzungszustand mit ASP.NET AJAX und ASP.NET verwalten WebServiceSession.aspx
< ! OOCTYPE html PUBLIC "-/ /W3C1/OTO XHTML 1.0 Transitional//EN" ''http://1rMW . w3. org/TR/xhtml1/DTO/xhtml1-transitional. dtd" >
[System.Web.Script.Services.ScriptMethod) public static float DivideNumbers(int a, int b)
{
if (b oo O) { throw new DivideByZeroException(); )
else { return (float)a I b; )
)
Komplexe Daten mit dem Server austausc:hen
107
Beispiel 5-6: Eine Seite, die komplexe Objekte von einer Webmethode erhält (Fortsetzung)
Abbildung 5-5 zeigt die Ausgabe dieses Skripts: Es werden das Divisionsergebnis und der Zeitstempel vom Server angezeigt.
e
�tp:f,4oul1ost:2M6fASPt-ET"-lAX�)C."SPl(
!D
�
3
I/� Iiz.,r,&en teieni
=
Q.75(berechnelum 12:2557)
<
)
Abbildung 5-5: Die komplexen Informationen vom Server werden angezeigt. Wenn Sie sich den HTTP-Verkehr anschauen, den dieses Skript generiert, sehen Sie sehr gut, wie die komplexen Daten in JSON transformiert werden (siehe Abbildung 5-6). tj ASP.NEl AJÄX - MoZll1a firefox - + I
3
..
i!!
1/ 4
=
z..tion teien I
HTMl
- ldendedOiYid Headers
---,---
0.75 (beredlnet um 13 05:48j
"'".. lnSPKt C\ooar I AI COfIsoie
�§�
C55
KTM.
CSS
5cnpt
locat.ost:2648 68 b
Post
JS DOM
KI-fI.
RHj)OnSe
..
.
, ..,
Abbildung 5-6: Die komplexen Informationen werden in JSON serialisiert.
108
I,HI
� R.osh
Nd
Kapitel $: Webservic@s
-
Bisher haben Sie besondere Webservice-Features kennengelernt, die ASP.NET AJAX bie tet und die sich mit JavaScript allein nur sehr schwer erreichen liesen. Das ASP .NET AJAX-Framework ist sehr gut in .NET-Webservices integriert, und das macht es sehr gut dafür geeignet, die heiden Technologien, JavaScript (elient) und ASP.NET (Server), zu verknüpfen.
Webservices mit JavaScript konsumieren Die automatischen Mechanismen, die ASP.NET AJAX für den Zugriff auf Webservices bietet, sind leicht zu verwenden, weil sie sich um einen Großteil der Arbeit kümmern. Es gibt allerdings Situationen, in denen diese Mechanismen nicht funktionieren. Stellen Sie sich beispielsweise vor, dass Sie einen Aufruf an einen Webservice (in der gleichen Domain) haben, der nicht in .NET, sondern in einer anderen serverseitigen Technologie wie PHP oder Java geschrieben ist. Oder nehmen Sie an, dass Sie ASP.NET AJAX aus irgendeinem Grund nicht verwenden können (beispielsweise aufgrund von Unterneh mensrichtlinien bezüglich externer Module oder aufgrund der Ablehnung bestimmter Lizenzen). Aber dieses Buch beschreibt nicht nur, wie man ASP.NET AJAX verwendet, um Ajax-gesteuerte ASP.NET-Anwendungen zu schreiben. Es beschreibt auch, wie man die zugrunde liegenden Technologien verwendet. Dieser Abschnitt zeigt deswegen alter native Möglichkeiten auf, um entfernte Webservices von JavaScript aus aufzurufen. Bevor wir ins Detail gehen, sollten Sie sich noch einmal in Erinnerung rufen, dass das Java Script-Sicherheitsmodell Cross-Domain-Scripting verbietet. Das bedeutet, dass Sie mit JavaScript (das implizit XMLHttpRequest nutzt) nicht auf entfernte Webservices zugreifen können. Es gibt zwei Wege, über die ein Webservice programmiertechnisch mit JavaScript auf gerufen werden kann. Sie können entweder auf XMLHttpRequest vertrauen oder eine geeignete SOAP HTTP-Anfrage schreiben und dann die Daten auswerten, die vom Server zurückgeliefert werden. Das ist ziemlich kompliziert und sehr fehleranfällig. Ein viel besserer Ansatz zur Lösung dieses Problems ist es, eine eingebaute Technologie oder eines der offziellen Browser-Addons zu verwenden. Unglücklicherweise verwenden die beiden wichtigsten Browsertypen, Internet Explorer und Mozilla (einschließlich Firefox, Epiphany, Camino und anderen), vollständig unter schiedliche Ansätze beim Aufruf von Webservices. Deswegen müssen wir jetzt getrennten Pfaden folgen und diese beiden Browser separat behandeln. Am Ende dieses Abschnitts werden wir die beiden unterschiedlichen Programmiermodelle verschmelzen, um em mehr oder minder browserunabhängiges Skript zu erzeugen.
Webservices und Internet Explorer Vor einigen Jahren begann Microsoft mit der Arbeit an Skriptcode, der es ermöglichen sollte, Webservices aus Browsern heraus aufzurufen. Im Wesentlichen instanziiert der Code ein XMLHttpRequest-Objekt, richtet die erforderlichen HTTP-Header für eine
Webservices mitJavaScript konsumieren I 109
SOAP-Anfrage ein, erzeugt den Anfrage-Body, wartet auf die SOAP-Antwort und trans formiert diese wieder in etwas, das JavaScript nutzen kann. Zusätzlich kann der Code die WSDL-Beschreibung des Webservice parsen und ein lokales Proxy-Objekt gene neren. Der Grundgedanke ist einfach, die Implementierung ist es nicht. Die endgültige Version des Codes (Version 1.0. 1 . 1 120) besteht aus 2300 Codezeilen. Aber im Jahre 2002 hat Microsoft die Komponente aufgegeben, die man geschrieben hatte. Das ist schade, ins besondere weil diese auch heute noch gut funktioniert. Glücklicherweise ist der Code in den Archiven des MSDN unter http://msdn.microsojt.com/archive/en-us/samples/internet/ behaviors/library/webservice/dejault.asp immer noch verfügbar. Laden Sie die Datei webservice.htc herunter, und speichern Sie sie in dem Verzeichnis, in dem sich Ihre Beispielskripten befinden. Die Dateinamenserweiterung .htc steht für »HTML Control« (HTML-Steuerelement), was auch unter dem Namen Internet Explorer-Verhalten bekannt ist. Indem Sie einen CSS-Style einsetzen, der nur im Inter net Explorer unterstützt wird, können Sie die Datei in Ihre Anwendung laden:
< /div>
Der Name, den Sie im id-Attribut angeben, kann in JavaScript verwendet werden, um auf das HTML-Steuerelement sowie den Webservice zuzugreifen, mit dem es verknüpft ist. Diese »Verknüpfung« kann bewirkt werden, indem ein Link auf die WSDL-Beschrei bung des Webservice angegeben wird, den Sie verwenden wollen. Die Methode der .htc Datei, die Sie für diese Aufgabe benötigen, ist useService( ) . Sie müssen auch einen ein deutigen Bezeichner angeben, um später auf den jeweiligen Webservice zuzugreifen:
WebService . useService( "MathService. asmx ?WSDL", "MathService" ) ; Dann rufen Sie den Webservice auf. Allerdings ist die Reihenfolge der Parameter für die entsprechende Methode callService ( ) etwas anders als bei dem Proxy-Objekt, das ASP.NET AJAX erzeugt. Die folgenden Parameter sind erforderlich: •
eine Referenz auf die Callback-Methode
•
der Name der Webmethode, die aufgerufen werden soll
•
der/die Parameter, der/die dem Webservice übergeben werden soll(en)
Nebenbei bemerkt: Eine Fehlerbehandlung wird nicht unterstützt (im Unterschied zu ASP.NET AJAX, wo dem Clientskript die Exception-Informationen geliefert werden). Im Fall des MathService-Webservice führt der folgende Aufruf die Division durch:
Die Callback-Funktion erhält das Ergebnis als Objekt, dessen value-Attribut den Rück gabewert des Webservice enthält:
function callComplete(result) { document.getElementsByld(" c") . innerHTML = result. value; } Beispiel 5-7 zeigt den vollständigen Code für dieses Beispiel. Beispiel 5-7: Einen Webservice vom Internet Explorer aufrufen
MathServicelnternetExplorer.htm < ! OOCTYPE html PUBLIC "-/ /W3C1/DTO XHTML 1.0 Transitional/ /EN" ''http://1rMW . w3. org/TR/xhtmll/DTO/xhtmll-transitional. dtd" > o.857142866
Webservices mitJavaScript konsumieren I 113
11 .
Gil "','
In Anhang A finden Sie mehr Informationen dazu, wie Sie Zugriff auf die
��, HTTP-Anfragen erhalten, die von Ajax-Anwendungen gesendet werden, . �' sowie allgemeine Informationen zum Debugging von Ajax-Anwendungen.
Wenn wir auf Basis der Darstellung der XML-Daten arbeiten, können wir erkennen, dass die folgenden Schritte erforderlich sind, um an den eigentlichen Rückgabewert, 0 . 857142866, zu kommen: •
Wir müssen die Eigenschaft body verwenden, um Zugriff auf das -Ele ment zu erhalten.
•
Wir müssen die Eigenschaft firstChild verwenden, um auf das -Element zuzugreifen.
•
Wir müssen noch einmal firstChild verwenden, um auf das Element zuzugreifen.
•
Wir müssen eine dritte firstChild-Referenz verwenden, um auf den Textknoten unter dem Element zuzugreifen.
•
Wir müssen die Eigenschaft data verwenden, um auf den Text Im Textknoten zuzugreifen.
Hier ist der JavaScript-Code, den Sie benötigen, um das Ergebnis des Webservice Aufrufs auszulesen:
function callComplete(result, soapcall, status) { document. getElementByld(" c") . innerHTML = result.body. firstChild.firstChild.firstChild.data; } Wenn Sie all diese Elemente zusammensetzen, erhalten Sie den Code, der in Beispiel 5-8 gezeigt wird. Beachten Sie, dass Sie eine Internetverbindung benötigen, damit das funk tioniert, da Mozilla auf die SOAP-Schemainformationen zugreift. Beispiel 5-8: Einen Webservice in Mozilla-Browsern aufrufen
MathServiceMozilla.htm < I DOCTYPE html PUBLIC "-IIW3CJ/DTD XHTML 1.0 TransitionalJ/EN" ''http://ww. w3. org/TR/xhtmll/DTD/xhtmll-transitional. dtd" > [...J Wenn Sie eine ID für das UpdatePanel-Steuereiement angeben, haben Sie sogar SmartTag Unterstützung in der Entwurfsansicht von Visual Studio. Aktuell ist die einzige Smart Tag-Aktion allerdings, der Seite den ScriptManager hinzuzufügen. Die eigentliche Anneh mlichkeit ist die Möglichkeit, Datentabellen aus dem Datenbank-Explorer in das UpdatePanel-Steuereiement zu ziehen. Abbildung 6-1 zeigt das UpdatePane1-Steuereiement in der Entwurfsansicht. .
�el
� �
pdatePanel . UpdatePaneI l
U pda tePa n el-Aufga ben
Add Scr' Manage<
Jj Abbildung 6-1: Das UpdatePanel-Steuerelement in der Entwurfsansicht Um zu demonstrieren, dass tatsächlich keine vollständige Aktualisierung der Seite statt findet, fügen wir der Seite noch ein Label-Steuerelement hinzu:
Dieses Label-Steuerelement wird die aktuelle Zeit auf dem Server anzeigen. Wenn es eine Seitenaktualisierung gibt, würde Code wie der folgende das Label-Steuerelement aktuali sieren.
protected void Page_Load(object sender, EventArgs e) { CurrentTime.Text = DateTime. Now.ToLongTimeString(); } Beispiel 6-1 zeigt den vollständigen Code für dieses Beispiel.
ln
I Kapitel6: UpdatePanel: NurTeile einer Seite aktualisieren
Beispiel 6-1: Ein GridView-Steuerelement, das ohne Seitenaktualisierung aktualisiert wird
UpdatePanel.aspx < ! OOCTYPE html PUBLIC "-//W3C1/DTO XHTML 1.0 Transitional/ /EN" ''http://1rMW . w3. org/TR/xhtmll/DTO/xhtmll-transitional. dtd" > protected void Page_Load(object sender, EventArgs e) { CurrentTime.Text = DateTime.Now.ToLongTimeString(); } ASP.NET AJAX - Mozilla Firefox
6'
+ .
r;]§�
[9.ht1J):/�t:26'18/A.SPNETA.)AX�tePanel.a5Px
16:01-17
Vendor1D AccounlNumber
tlame
CreditRating PreferredVendor$tatus Acli'
Bearbeiten 1
INTERNATOOQ1
Bearbeiten 2
ELECTRONOO02 Bike Repa lr 1
International 1
El ectronic
8. Supplies
Bearbellen 3
PREI.UEROOO1
Bearbeiten .4
COI.1FORTOO 0 1
Sport, Inc. Cemlort Premier
1
R e ad
Bicycles Bearbeiten 5
1.1ETROSPOO01
I.Ietro Sport
n
Equip me t Green Lake
Bearbeiten 6
GREENLAOO01
Bike Company
Bearbeiten 7
/,lOUNTjlJNOOO1
IAountain
Works )
< F6"
v
(!,
Abbildung 6-2: Ein Postback des GridView-Steuereiements auslösen
Wenn Sie das Drag-and-Drop-Feature von Visual Studio nutzen und die Tabelle Vendor auf die Seite in der Entwurfsansicht ziehen, erhalten Sie eventuell im Browser (insbesondere wenn Sie eine Vor-SPI-Version von Visual Studio oder VWD einsetzen) eine ASP.NET-Fehlerme1dung, weil Vendor zwar ein eindeutiger Tabellenname ist, dieser in der Datenbank aber mit einem Namensraum definiert wurde. Der richtige Name ist Purchasing. Vendor. Deswegen müssen Sie den gesamten automatisch gene rierten Code durchgehen und alle Vorkommen von [Vendor 1 durch [Purchasing. Vendor 1 ersetzen. Seien Sie sich aber möglicher Nebeneffekte bewusst. Beispielsweise sind File-Uploads zurzeit problematisch, wenn sie in einem UpdatePanel-Steuerelement erfolgen. Deswegen sollten Sie diese Effekte spärlich einsetzen. Ein gewöhnliches -HTML-Element ist ausreichend. Sie müssen sich dann nicht auf ASP.NET AJAX stützen, wodurch Ihre Anwendung etwas schwerer zu debuggen würde, wenn etwas schiefläuft. Unter »Zum weiteren Lesen« finden Sie Verweise auf eine Liste mit Steuerelementen, die mit Update Panel kompatibel sind.
Einen Seitenbereic:h aktualisierbar mac:hen
125
\:) ASP.NIT AJAX - Mazilla Firefox Qa�
Im Timer-Steuerelement können Sie jetzt jedes Mal, wenn das Tick-Event ausgelöst wird, eine Aktualisierung des UpdatePanel auslösen - mit anderen Worten also in festgelegten Intervallen. Das kann programmiertechnisch durchgeführt werden. Aber wie üblich gibt es auch einen deklarativen Weg.
126 I Kapitel6: UpdatePanel: NurTeile einer Seite aktualisieren
Im UpdatePanel-Steuerelement kann das -Element verwendet werden, um Event-Trigger zu definieren, die bewirken, dass das UpdatePanel-Steuerelement aktuali siert wird. Wenn das Trigger-Event eintritt, durchläuft das UpdatePanel seinen Aktualisie rungszyklus. Diese beiden Eigenschaften müssen gesetzt werden: ControlID Der Name des Steuerelements, das das Event auslöst EventName Der Name des Events, das die Aktualisierung auslöst Es gibt zwei Arten von Triggern: AsyncPostBackTrigger Trigger arbeiten asynchron - das sollten Sie vorziehen. PostBackTrigger Trigger arbeiten synchron - das sollten Sie normalerweise nicht verwenden. Um die Verwendung des Timers mit dem UpdatePanel-Steuerelement zu demonstrieren, werden wir das Label-Steuerelement aus dem vorangehenden Beispiel verwenden, um im UpdatePanel-Steuerelement die aktuelle Zeit anzuzeigen. Es wird also Folgendes passieren: •
Wenn die Seite zum ersten Mal geladen wird, wird das Label-Steuerelement auf die aktuelle Zeit gesetzt.
•
Alle fünf Sekunden tritt im TimerControl das Tic k-Event ein, das die Aktualisierung des Inhalts des UpdatePanel-Steuerelements bewirkt (das wird von ASP.NET AJAX automatisch durchgeführt) .
Beispiel 6-2 zeigt den vollständigen Code für dieses Beispiel.
Beispiel 6-2: Ein Panel nach festgelegten Zeitintervallen aktualisieren
Abbildung 6-4: Der Zeitstempel wird alle fünfSekunden aktualisiert.
Einen Bereich programmiertechnisch in regelmäßigen Intervallen aktualisieren Die wichtigste Methode, die vom UpdatePanel-Steuerelement veröffentlicht wird, ist Update( ) - wie Sie wahrscheinlich erwarten, aktualisiert sie das Panel. Eine Möglich keit, diese Methode zu nutzen, ist die Behandlung des Tick-Events des TimerControl Elements. In Markup machen Sie das so:
Dann können Sie im Servercode einen gewöhnlichen ASP,NET-Event-Handler schreiben, der die Update-Methode des UpdatePanel-Steuerelements aufruft:
128 I Kapitel6: UpdatePanel: NurTeile einer Seite aktualisieren
protected void UpdateContents(object { if (new Random().Next(o, 4) == 1) { UpdatePanel1.Update( ) ; } }
0,
EventArgs e)
Dieser Code aktualisiert das Panel (und damit die Anzeige, die der Benutzer sieht) bei durchschnittlich jeder vierten Anfrage. Das Timer-Steuerelement bewirkt alle fünf Sekun den einen Auffrischungsaufruf. Der Code entscheidet dann zufällig, ob die aktuelle Auffrischungsanforderung das Panel aktualisieren soll. In der Praxis würden Sie wahr scheinlich prüfen, ob sich bestimmte Daten (in einer Datenbank bzw. einer Datei) geän dert haben, und würden dann die Aktualisierung auslösen. Das UpdatePanel-Steuereiement von ASP.NET AJAX unterstützt zwei Modi, die Sie im UpdateMode-Attribut des Steuerelements setzen: Always Der Inhalt des UpdatePanel-Steuereiements wird immer aufgefrischt, wenn ein Post back erfolgt (das Default-Verhalten). Conditional Der Inhalt des UpdatePanel-Steuereiements wird nur aufgefrischt, wenn ein Trigger verwendet wird oder die UpdateO-Methode des UpdatePanel aufgerufen wird (wie in diesem Beispiel) oder wenn das Eltern-Panel eines eingebetteten UpdatePanel-Steuer elements aktualisiert wird. In der Regel führt der Conditional-Modus dazu, dass weniger Daten zwischen Client und Server ausgetauscht werden, und optimiert damit die Leistung des UpdatePanel-Steuerele ments. Wenn es möglich ist (d.h., wenn Sie Trigger oder Update( ) einsetzen) , sollten Sie also UpdateMode= "Conditional" verwenden. Beispiel 6-3 zeigt den vollständigen Code für ein UpdatePanel-Steuereiement, das in zufäl ligen Zeitabständen aktualisiert wird. Die Änderungen werden dabei hervorgehoben.
Beispiel 6-3: Ein Panel programmiertechnisch aktualisieren
UpdatePanelTimerCode.aspx < I DOCTYPE html PUBLIC "-IIW3CJ/DTD XHTML 1.0 TransitionalJ/EN" ''http://www. w3. org/TR/xhtml1/DTD/xhtml1-transitional. dtd" > private void UpdateContents(object 0, EventArgs e) { if (new Random() .Next(O, 4) 1) { UpdatePanel1.Update()j ) ) ==
Einen Seitenbereic:h aktualisierbar mac:hen I 129
Beispiel 6-3: Ein Panel programmiertechnisch aktualisieren (Fortsetzung)
Windo...,.·......th.ntif,zi."mg zur ld."tlfiz'.runll von e.nut:!.rn. Benutzer mit el"em guiligen Wlndo...,.-Benutz.r"am,," und
·KennYlrt kORn,," auf Ih,. Sit" zug,,,,f,,".
Abbildung 8-2: Den richtigen Authentifizierungstyp setzen
150
Kapitel8: Den ASP.NETAJAX-Authentifizierungsdienst nutzen
�§rg)
Klicken Sie dann auf den Link Benutzer
erstellen, und geben Sie die Berechtigungsinfor
mationen für zumindest einen neuen Benutzer ein (siehe Abbildung 8-3). Iö ASP.HIT We-b.lnwendungsv..,..,.alturrg .
Moz,lla
�rQl�
Firefox
+ .
-
-
Neues Konto eonnchten
l I Kennwort bestaooen: [ E·Maol: : ßenvtl:emame:
Kennwort:
Sicherheitsfraoe:
SlCherheotsantwort:
Abbildung 8-3: Erzeugen Sie einen neuen Benutzer (oder gleich zwei, drei) Wenn Sie gerade die
Web.config
in Ihrer IDE geöffnet haben, bevor Sie das ASP.NET
Konfigurationswerkzeug verwenden, fordert Visual Studio (oder Visual Web Developer) Sie auf, die Datei neu zu laden. Der Grund: Ihre Aktionen im Konfigurationsprogramm führten dazu, dass
Web.config im
-Knoten die folgende Zeile hinzugefügt
wurde:
Es gibt eine weitere Konfigurationseinstellung, die Sie
Web.config
hinzufügen müssen,
unglücklicherweise ohne Hilfe eines GUI-Tools. Im vorangegangenen Kapitel wurde
Web.config der -Knoten hinzugefügt. Fügen Sie in diesen Knoten ein -Element ein, und setzen Sie sein enabled-Attribut auf true, damit Sie das folgende Ergebnis erhalten:
Das richtet den erforderlichen JavaScript-Code ein, der den Client mit der Server-API ver bindet.
Achten Sie darauf, dass Sie Ihre Anwendung gemäß der Anweisungen aus dem letzten Kapitel und vom Anfang dieses Kapitels konfiguriert haben, damit Profil-API und Authentifizierungs-API sowie die verwendeten Profil eigenschaften unterstützt werden.
login und logout Die Klasse Sys. Services .AuthenticationService enthält zwei Methoden für die Unterstüt
zung der Formularauthentifizierung von ASP.NET AJAX: login ( ) und logout ( ) . Begin nen wir damit, einen Benutzer einzuloggen. Diese Methode hat nicht weniger als acht
Argumente:
userName Der Benutzername
password Das damit verknüpfte Passwort
isPersistent Gibt an, ob der Benutzer über ein persistentes Cookie dauerhaft eingeloggt werden soll (der Standardwert ist false) .
redirectUrl
Die URL, zu der der Browser umgeleitet werden soll, nachdem der Benutzer einge loggt worden ist, oder null, wenn keine Umleitung erfolgen soll (Standard)
customlnfo Aktuell nicht verwendet
loginCompletedCallback Die Funktion, die nach einem erfolgreichen Login aufgerufen werden soll
failedCallback Die Funktion, die nach einem nicht erfolgreichen Login aufgerufen werden soll
userContext Daten, die den Callback-Funktionen übergeben werden sollen Sie haben zwei Optionen für die Implementierung der Authentifizierung:
1.
Rufen Sie login ( ) auf, und lassen Sie JavaScript zu einer anderen Seite umleiten, indem Sie redirectUrl setzen.
152 I Kapitel8: Den ASP.NETAJAX-Authentifizierungsdienst nutzen
2. Rufen Sie
loginO auf, und nutzen Sie die Callback-Funktionen (loginCompletedCallback, failedCallback), um die Authentifizierungsergebnisse zu verarbeiten.
Ziemlich oft wird die zweite Möglichkeit vorgezogen. Eine Umleitung deutet einen Datenschutz an, der nur auf JavaScript basiert, und das ist - wie bereits gesagt - ein sehr unsicheres Verfahren. Das Ausloggen erfolgt mit der Methode logoutO . Sie unterstützt »nu[(� vier Argumente:
red irectUr1 Die URL, zu der der Browser umgeleitet werden soll, nachdem der Benutzer ausge loggt worden ist, oder null, falls keine Umleitung erfolgen soll (Standard)
logoutCompletedCallback Die Funktion, die nach einem erfolgreichen Ausloggen aufgerufen werden soll
failedCallback Die Funktion, die nach einem gescheiterten Ausloggen aufgerufen werden soll
userContext Daten, die an die Callback-Funktionen übergeben werden sollen. Diese beiden Funktionen werden jetzt zur Datei ProfileGroup.aspx aus dem letzten Kapi tel hinzugefügt, wodurch eine neue Datei erinnern werden, dient die Seite
Authenncation.aspx erstellt wird. Wie Sie sich ProjileGroup.aspx dem Benutzer als Login-Formular und
speichert den Benutzernamen und das Passwort in Profilvariablen. Bisher hatte das But ton-Element des Formulars noch keine Funktion. Das wird jetzt sofort geändert. Erst ent fernen wir den gesamten Dummy-JavaScript-Code, der mit dem Button verknüpft ist, sodass nur noch das folgende Markup bleibt:
In der Funktion pageLoadO wird ein Click-Event-Handler für den Button definiert:
$addHandler( $get ("Button1" ) , "click" , doClick); Die im vorangehenden Codefragment referenzierte Funktion doClickO untersucht dann die Beschriftung des Buttons. Ist diese " Einloggen" , versucht die Anwendung, den Benut zer einzuloggen, ist sie "Ausloggen", versucht die Anwendung, den Benutzer auszuloggen. Die größte Herausforderung ist jetzt das Setzen der erforderlichen Argumente für die Methoden login() und logout( ) . Da die Benutzerberechtigungen ohnehin im Profil gespeichert sind, ist kein persistentes Login erforderlich. Außerdem wollen wir den Benutzer nicht umleiten, nachdem wir ihn ein- oder ausgeloggt haben. Und wir wenden auch den Trick aus dem vorangegangenen Kapitel an und setzen das Argument userCon
text auf Werte, die es uns ermöglichen, die gleichen Callback-Funktionen für Login und Logout zu verwenden.
function doClickO { switch ($get(" Button1"). value) { ca se "Einloggen" :
Die Funktion loginError( ) kümmert sich um nicht erfolgreiche Login- und Logout-Ver suche, beispielsweise aufgrund ungültiger Berechtigungsinformationen, eines fehlenden Benutzernamens oder einer falschen Serverkonfiguration. Dann wird eine geeignete Feh lermeldung im HTML-Label angezeigt:
) Schließlich gibt auch die Funktion loginComplete ( ) eine Statusmeldung aus. Zusätzlich ändert sie noch das Login-Formular. Nachdem sich der Benutzer eingeloggt hat, werden beide Textfelder deaktiviert und die Button-Beschriftung von " Einloggen" in "Ausloggen" geändert. Wenn sich der Benutzer ausgeloggt hat, wird die Button-Beschriftung wieder in
" Einloggen" geändert, und die beiden Textfelder werden wieder aktiviert.
Beispiel 8-1 zeigt den vollständigen Code für dieses Beispiel. Denken Sie daran, die erfor derlichen Änderungen an der Web.config-Datei vorzunehmen, bevor Sie dieses Beispiel ausführen.
Beispiel 8-1 : Benutzer mitjavaScript authentifizieren
Benutzername: Passwort: < span id=" statusText" runat=" server" > < / span> -Element, das genutzt wird, um das lokalisierte Datum dyna misch auszugeben. Beachten Sie das nicht-trennende Leerzeichen ( ) im (span>-Ele ment - das ist für den JavaScript-Code wichtig. Ein Internet Explorer-Verhalten würde dafür sorgen, dass ein gewöhnliches Leerzeichen nicht funktionieren würde.
 j Jetzt können wir etwas JavaScript-Code hinzufügen, der die in der externen JavaScript Datei definierten Variablen dateformat und daynames einsetzt, um eine lokalisierte Datumsdarstellung zu erstellen:
function pageLoadO { var d = new Date()j var datestring = dateformat .replace("ss", daynames[ d.getDay() J ) .replace("dd", d.getDate()) .replace("rrm", d.getMonthO + 1) .replace("yyyy", d.getFullYear( )) j $get (" date" ) . firstChild. nodeValue = datestringj )
Bisher haben wir nichts Besonderes gesehen. Aber jetzt werden ASP.NET und ASP.NET AJAX zu zaubern beginnen. Als Erstes lädt ASP.NET AJAX die externe JavaScript-Datei und (das ist die Zauberei) ermittelt auf Basis des Dateinamens die richtige Datei für die aktuelle Sprache und das aktuelle Locale. Im ScriptManager-Steuerelement nutzen Sie das
Lokalisierung I
161
-Element, um die Datei Dayname.js zu laden. Zwei Attribute kümmern sich um fast alles andere:
ResourceUICultures (Attribut von ar . wählen Sie die spr� fi.r die D",.steb!g von webseoten in der von lmen bevorll.l\lten Reihenfolc;je. 5p"achen 11 bevorll.l\lter Reihenfol(je: Deutsdlft)eutsdi.end [de1:le)
Abbildung 9-10: Die bevorzugten Sprachen in Firefox ändem SpracheinsteIlung
""""""...... listen Sie die 5p"ad'ien 11 der Qe'M..OSdlterl Rehenfoloe auf, die Sie run lesen von Websltes verwenden. FOoen Sie ru" die Iwlzu, die Sie v.vkIich verwenden, da � ZelCl'len Z\S lrn� von
Deutsch I
rg)
Webs!tes 11 anderen Sp'adlen vef'kendet werden kbmen. Spr.,che:
(Deutsd'0od) [de)
Prafi)(- l.I'ld Suffi)(opbonen
Kel1 "wtffl" "" den Anfo!ll'lg eIlQe,"ebener Webad'es� O Iwlzu1iJQen
l� Sie das Suffi)( Rost (1. B. .de), das zu eIlQe,"ebenen Webaaessen beim � von 'Strg + t..lrt1sdllaI + Eingabe" Iwl�fuo:lt werden d. Suffi)(:
Abbildung 9-11: Die bevorzugten Sprachen im Intemet Explorer ändem Kehren wir zu unserem Thema ASP .NET AJAX und Datumsglobalisierung zurück. Die Methode Date _loca1Format() nutzt Platzhalter und ersetzt diese durch lokalisierte Namen für die Wochentage und Monate. Der folgende Code gibt etwas Ähnliches wie »Mittwoch,
1 . Mai 2007« aus - natürlich in Abhängigkeit von der SpracheinsteIlung des Browsers:
function pageLoadO { $get("date" ) . firstChild. nodeValue =
Globalisierung und Internationalisierung I 17S
(new DateO) . 1ocaleFormat( "dddd, dd. MMMM yyyy"); } Es ist allerdings noch ein weiterer Schritt erforderlich. Die ASP.NET-Anwendung muss das richtige Locale einrichten. Das Locale kann in
web.config, über Programmcode oder
über Markup in der Seite gesetzt werden. Verweise auf Informationen
zu
verfügbaren
Optionen finden Sie im Abschnitt »Zum weiteren Lesen« . Im folgenden Beispiel wird das Locale über die @ Page-Direktive gesetzt. Wie könnten ein bestimmtes Locale angeben, ziehen es aber vor, dass ASP.NET AJAX die erforderlichen Einstellungen auf Basis des Accept - Language-HTTP-Headers ermittelt. Die folgende Deklaration kümmert sich darum:
Und das war's schon - Beispiel 9-8 zeigt den vollständigen Code,
der diesmal angenehm
kurz ist.
Beispiel 9-8: Ein Datum globalisieren
Globalization.aspx
< I DOCTYPE html PUBLIC "/ /W3C/ /DTO XHTML 1.0 Transitional! /EN" ''http://www.w3.org/TR/xhtmll/DTO/xhtml1transitional.dtd">
[
Abbrechen
Abbildung 10-3: Der VSI-Installer für das Toolkit
rzJr8J
Neue Web5ite
Von V..ualStudio
install"'rt" Vorli!9"n
�ASP.f'fl·Web§ltr:
�ASP.t€T AlAX� WHl Siu.
'.I\SP.tfl.W�t
A.lAX Control Toollt WHl Si�
v
Abbildung 10-4: Die Toolkit-Vorlage
184
�SWm-!G1 fIs per� WM�
I,jASP,r-ET AlAX CTl'� W�. . tft,l_e Wms.u.
Kapitel 10: Das Control Toolkit verwenden
Der nächste Schritt bei der Verwendung des ASP.NET AJAX Control Toolkits ist es, die Steuerelernente der Toolbox von Visual Studio hinzuzufügen. Lassen Sie die Toolbox in der Entwurfsansicht der IDE anzeigen. Klicken Sie dann mit der rechten Maustaste auf die Toolbox, und wählen Sie Registerkarte hinzufügen. Geben Sie der neuen Registerkarte den Namen ASP.NET AJAX
Control Toolkit
(Sie können natürlich einen Namen eigener
Wahl nehmen). Klicken Sie mit der rechten Maustaste auf die neue Registerkarte, und wählen Sie
box-Elemente auswählen
(oder einfach
Elemente auswählen
Tool
in Visual Web Developer) .
Fügen Sie die ASP.NET AJAX Control Toolkit-Assembly hinzu. Das ist die Datei
Ajax ControlToolkit.dll, die sich im Bin-Ordner der aktuellen Website auf Basis der ASP.NET AJAX Control Toolkit Web Site-Vorlage befindet. Anschließend hat die Toolbox einige neue Einträge, wie in Abbildung 10-5 zu sehen ist. (Beachten Sie, dass die Toolbox-Ele mente erst sichtbar sind, wenn Sie ein Dokument wie eine ASP .NET-Seite geöffnet haben, in dem Sie sie verwenden können.) Toobox
I ASP.NET AJAX LinkButton Abbildung 10-6 zeigt das Ergebnis, das im Browser erscheint. Wenn auf das LinkButton Steuerelement geklickt wird, erscheint das Pop-up-Fenster. Wird auf Nein geklickt, wird das Formular nicht an den Server geschickt. Die anderen Toolkit-Erweiterungen funktionieren auf ähnliche Weise. Fügen Sie einfach die entsprechenden Erweiterungssteuerelemente der Seite hinzu (erzeugen Sie ein -Element) , und setzen Sie die Eigenschaften der Erweiterung. ".
Aus javaScript-Perspektive ist der Effekt trivial, den ConfirmButtonExten der bietet. Der folgende JavaScript-Code reicht aus, um einem gewöhnli: chen HTML-Hyperlink eine Bestätigungsaufforderung hinzuzufügen, . etwas, das das ConfirmButtonExtender-Steuerelement noch nicht kann): Go to the ASP.NET AJAX homepage Diese Erweiterung zeigt, dass ASP.NET AJAX mehr als nur ein Ajax-Tool kit ist - dank des Control Toolkits wird es auch zu einem JavaScript-Tool kit.
Abbildung 10-6: Der Bestätigungstext, der angezeigt wird, wenn auf den Button geklickt wird
Zusammenfassung Dieses Kapitel hat das ASP .NET AJAX Control Toolkit vorgestellt, gezeigt, wie das Paket installiert wird, und ein erstes Beispiel präsentiert. Lesen Sie unbedingt die folgenden Kapitel, die viele der aufregenden Steuerelemente und Features vorstellen werden, die von diesem Open Source-Projekt geboten werden.
Zum weiteren Lesen http://www.codeplex.com/AtlasControlToolkit Die ASP.NET AJAX Control Toolkit-Homepage auf CodePlex
http://ajox.asp. netl0jaxtoolkitl Eine Live-Version des Control Toolkits
188
I
Kapitel 10: Das Control Toolkit verwenden
KAPITEL 1 1
Einer Webseite Animationen hinzufügen
Eine Schlüsselkomponente des ASP.NET AJAX Control Toolkits ist ein mächtiges Ani mationsframework, das verschiedene Möglichkeiten zur Erstellung komplexer Animatio nen bietet, ohne dass dafür eine umfangreichere JavaScript-Programmierung erforderlich ist. In diesem Kapitel werden wir betrachten, wie man das macht. Wir streifen dabei auch ein verwandtes Feature des Control Toolkits - die Drag-and-Drop-Unterstützung. Beachten Sie, dass Sie zur Arbeit mit den Beispielen in diesem Kapitel das ASP .NET AJAX Control Toolkit installiert haben müssen und eine Website brauchen, die für die Verwendung des Toolkits konfiguriert ist. Details finden Sie in Kapitel 10.
Animation Framework Wenn Sie ASP.NET AJAX nutzen wollen, um ohne großen Aufwand Animationen zu erstellen, haben Sie zwei Möglichkeiten (für beide gibt es keinen Support) . Entweder Sie nutzen die ASP.NET AJAX Futures, die verschiedene Animationsmöglichkeiten bieten (eine ausführliche Betrachtung finden Sie in Kapitel 19). Oder Sie können das ASP.NET AJAX Control Toolkit verwenden. Das Toolkit enthält nicht nur einige Websteuerele mente für ajaxige Animationseffekte, sondern ein vollständiges Animations-Framework, das in diesem Kapitel anhand von Beispielen erläutert wird. Es lässt sich schwer sagen, welche Möglichkeit am Ende gewinnen wird, ich aber würde auf das Control Toolkit set zen, da es mehr von den Bedürfnissen der Benutzer geleitet ist als die Futures. Aber das wird die Zeit zeigen.
Animationsgrundlagen Das Websteuerelement, das das Animations-Framework im Control Toolkit bietet, ist
AnimationExtender. Zunächst benötigen Sie die Eigenschaft TargetControlID, die die ID des Elements enthalten muss, das animiert werden soll:
d--
. . .
-->
I 189
Die eigentliche Animation wird jedoch im Element AnimationExtender definiert. Dort können Sie das XML-Markup angeben, das die Animation steuert. Der Wurzelknoten dieses Markups ist . Innerhalb dieses Knotens müssen Sie die folgenden Informationen angeben: •
Events: Wann eine Animation angestoßen werden soll, d.h., einen Trigger.
•
Animationstypen und Eigenschaften: Welche Animationen verwendet werden sol len, beispielsweise Fade, Bewegung, Größenveränderung und so weiter. (Mehr dazu erfahren Sie gleich.)
Beispiel 11-1 zeigt eine solche Animation. Im -Knoten steht der Knoten für eine Animation (oder Animationen) , die ausgeführt wird, nachdem die Seite vollständig geladen worden ist. In gibt es nur eine Animation, die durch ein -Element angegeben wird. Das Ziel wird also über drei Sekunden (Attribut Duration) mit 25 Animationsschritten (Attribut Fps, Frames per Second) ausgeblendet. Abbildung 11-1 zeigt den Browser mitten in dieser Animation.
Beispiel 11-1: Eine simple Fade-out-Animation
AnimationFade.aspx < I DOCTYPE html PUBLIC "J/W3C/ JDTD XHTML 1.0 TransitionalJJEN" ''http://www.w3.org/TR/xhtmll/DTD/xhtml1transitional.dtd"> ASP.NET AJAX dorm id="forml" runat="server">
.
-
protected void Page_load(object sender, EventArgs e) { string animations = " ASP.NET AJAX And here is frorn our sponsors . . .
Willkommen auf der ASP.NET AJAX Control Toolkit-Beispiel-Website.
Willkommen auf der ASP.NET AJAX Control Toolkit-Beispiel-Website. 204 I Kapitel 12: AutoverYolIständigung für Benutzereingaben, Spam-Bekämpfung und mehr
Beispiel 12-2: Den AlwaysVisibleControlExtender verwenden (Fortsetzung)
Willkorrrnen
Willkorrrnen
Willkorrrnen
Willkorrrnen
Willkorrrnen
Willkorrrnen
Willkorrrnen
Willkorrrnen
auf auf auf auf auf auf auf auf
der ASP .NET der ASP.NET der ASP .NET der ASP .NET der ASP .NET der ASP .NET der ASP.NET der ASP .NET
Willkommen auf der ASP.NET AJAA Contro l Toolkit·Beispiel·Website Willkommen auf der ASP.NET AJAA Control Toolkit·Beisplel·Webslte
17F���C-V----�M>�O� Willkommen auf der ASP.NET AJAA Control Toolkit-Belsplel-Website.
Abbildung 12-2: Das Banner erscheint in der linken oberen Ecke, auch wenn gescrollt wird.
Einem TextBox-Steuerelement eine Autovervollständigung hinzufügen Webanwendungen werden immer mehr wie Desktop-Anwendungen, und dieser Trend wurde durch Ajax-Technologien ermöglicht. Ein Feature, das einige Desktop-Anwen dungen haben, Websites üblicherweise aber nicht, ist eine Autovervollständigungsfunkti onalität: Wenn Sie in ein Textfeld etwas eingeben, schlägt die Anwendung für das Feld geeignete Daten nach (in den meisten Browsern beispielsweise eine Liste der zuvor in ähnliche Felder eingegebenen Daten) und bietet an, das Feld für Sie auszufüllen. Eine der ersten bekannten Webanwendungen, die ein solches Feature unterstützte, war Google Suggest (http://www.goog/e.com/webhp.comp/ete=l &h/=en) . Wenn Sie beginnen, in einem Feld etwas einzugeben, schlägt die Webseite nicht nur beliebte Suchbegriffe vor, sondern zeigt auch auch, wie viele Ergebnisse diese Suche wahrscheinlich liefern wird, wie Abbildung 12-3 zeigt. Mittlerweile wissen Sie, wie das gemacht wird: Ein XMLHttp Request wird an einen Webservice geschickt, der Suchbegriffe und die geschätzte Anzahl von Ergebnissen zurückliefert. Einem TextBox-Steuerelement eine Autovervollständigung hinzufügen I 20S
r=c'.'-:.-'c-��-----------,
''''' .v ' I'A' S"'P'.'N''E�T i'J aso
nel aso nel aso nel , aso nel � yeti type, "'� � a s o net aso net aso net aso nel
313X to o l kit aiax tuten al aiax control tool kit a !ax controls alax 1 0 aiax samoies aiax extensions aiax d ownload
�
aso ��: aia
��amDles
" M'''"WStn''
1 190000 _ull5
1 �o (IOD _Its
...rcu
p,,'
lr."�"!Ioo!J
l D1D OOO ,nul15
1 �� 000 '... u lt> uta Lum m Q.< ' 1 570.000 _ultt.
, 250 000
, 4� 000
,.",111 _ull3
1 � 000 rtiulll 1 290 000 'tilJlts
,... '
Abbildung 12-3: Google Suggest ASP.NET AJAX bietet eine Steuerelementerweiterung namens AutoCompleteExtender, die genau diesen Zweck erfüllt. Zu den Aufgaben, die bei der Implementierung dieses Fea tures anfallen, zählen die Programmierung des CSS und des JavaScripts, die erforderlich sind, um die Vorschläge anzuzeigen und sie mit der Tastatur navigierbar zu machen. Bei einer Erweiterung aus dem Control Toolkit wurde diese Arbeit bereits geleistet. Sie müs sen also nur noch das Feature anwenden und einen Webservice schreiben, der die Daten stellt. Beachten Sie allerdings, dass einige der verzwickteren Elemente von Google Sug gest (einschließlich der Tastaturnavigation) in der Erweiterung nicht vollständig imple mentiert sind. Aus der Perspektive eines Websteuerelements ist TextBox das einzige Element, für das eine Autovervollständigung sinnvoll ist. Hier ist also das Element:
Dann muss das ASP.NET AJAX-Steuerelement eingeschlossen werden: AutoComplete Extender. Mit diesem Element können mehrere Eigenschaften verwendet werden, um den Autovervollständigungseffekt zu konfigurieren. Die folgenden Elementattribute sind die wichtigsten:
TargetControlID Die ID des Steuerelements, dem Sie Autovervollständigung verleihen wollen ServicePath Der Pfad zu dem Webservice, der die Autovervollständigungsdaten generiert ServiceMethod Die Methode des Webservice, die Sie aufrufen, um die Autovervollständigungsda ten zu erhalten
206 I Kapitel 12: AutoverYolIständigung für Benutzereingaben, Spam-Bekämpfung und mehr
Hier ist etwas Beispiel-Markup für die Erweiterung:
Beispiel 12-3 zeigt, wie man eine ASP.NET-Seite mit einem Textfeld erzeugt, das ein Autovervollständigungsverhalten unterstützt. Beispiel 12-3: Einem Textfeld eine Autovervollständigung hinzufügen
AutoComplete.aspx < ! OOCTYPE html PUBLIC "-/ /W3C1/DTO XHTML 1.0 Transitional/ /EN" ''http: //www . w3. org/TR/xhtmll/DTO/xhtmll-transitional. dtd" > /l.l
Host: 1ocahost:3682 lUr·AQelt: MoZlla/5.0 C>Vindows; u, wndows NT 5. I: cIe; 1"01: 1,8,1.4) �{20070S15 Frefoxf,!.O.O.4
Act;'"Ot: r..xtfxml,�l!QnjxmI,�bQn{xhlrll +xmI.�xtft1!mI;Q-o.9,u.x�;Q-o.e,iMQOe/Pr9,-�;Q-o, S
SqlConnection conn = new Sq1Connection( "server=(10ca1) \ \SQLEXPRESS; Integrated Security=true; Initial Cata1og=AdventureWorks" ) ; conn,Open(); SqlCommand comm = new Sq1Co�nd( "SELECT TOP " + count + " Name FRQM Purchasing. Vendor WHERE Name LIKE ' " + prefixText + "%' " , conn); SqlDataAdapter adap = new Sq1DataAdapter(comm); DataSet ds = new DataSet( ) ; adap.Fill(ds); string[] vendors = new string[Math.Min(count, ds.Tables[O] . Rows.Count ) ] ; for (int i = 0 ; i < Math.Min(count, ds.Tab1es[0]. Rows.Count); i++) { vendors[i] = ds.Tables[O] . Rows[ i ] . ItemArray[O].ToString();
Einem TextBox-Steuerelement eine Autovervollständigung hinzufügen I 211
Beispiel 12-4: Ein Webservice. der mögliche Treffer abruft (Fortsetzung) )
return vendors; ) )
Jetzt ist es an der Zeit, das im Browser zu testen. Laden Sie die Seite, und geben Sie ein paar Buchstaben ein, mindestens drei - bei zwei oder weniger Buchstaben führt ASP.NET AJAX keinen Webservice-Aufruf aus. Werden Treffer gefunden, werden diese mit einer kleinen Verzögerung im Textfeld angezeigt. . ",
Bei dem in Beispiel 12-4 skizzierten Webservice kann Caching eine große Hilfe sein, insbesondere wenn immer wieder nach den gleichen Begriffen --: gesucht wird. Um Caching einzuführen, ändern Sie einfach das WebMethod Accribuc von GetVendors( ) so, dass es einen Wert für die Cache-Dauer ein schließt: [WebMethod(CacheDuration = 60) ] . Der Wert für CacheDuration wird in Sekunden gemessen. Das vorange hende Accribuc würde die Webservice-Ergebnisse also eine Minute cachen. Wenn Sie (wie in diesem Beispiel) Microsoft SQL Server als Datenbank Backend nutzen, können Sie eine SqlCacheDependency auf den DataSet Objekten erzeugen. (Verweise auf Informationen dazu finden Sie im Abschnicc »Zum weiteren Lesen«.)
Gil " ��, .
•
.
Wenn Sie keine Ergebnisse erhalten, versuchen Sie Folgendes: Es gibt mehrere Unterneh men, deren Namen mit dem Wort International beginnen. Die Eingabe dieses Worts sollte Ihnen eine hinreichende Anzahl von Treffern liefern. Abbildung 12-5 zeigt einige typische Ergebnisse. � ASP.NIT AJAX · Mozilla Firefox
Abbildung 12-5: ASP.NET AJAX schlägt Herstellernamen vor.
212 I Kapitel 12: AutoverYolIständigung für Benutzereingaben, Spam-Bekämpfung und mehr
�lQ]�
Einen Kalender an ein Textfeld knüpfen Seiten zum Buchen von Hotels, Flügen und allen möglichen anderen Dingen bieten ein Textfeld zur Eingabe eines Datums (beispielsweise für den Tag der Ankunft im Hotel oder den Tag des Abflugs). Als Erleichterung implementieren die meisten dieser Sites einen Kalender, in dem Benutzer ein Datum auswählen können. Sie können das über ein UpdatePanel und das Calendar-Steuerelement von ASP .NET implementieren, aber der CalendarExtender des ASP.NET AJAX Control Toolkits ist bequemer und bietet zusätzliche Features wie eine Lokalisierung. Wie Sie aus dem Namen ersehen können, ist CalendarExtender eine Erweiterung und muss deswegen an ein Steuerelement geknüpft werden (in der Regel ein Textfeld). Wenn Sie einen Blick auf Beispiel 12-5 werfen, werden Sie sehen, wie wenig Code erforderlich ist, um den Effekt zu erzeugen, der in Abbildung 12-6 gezeigt wird: Wenn der Benutzer auf das Textfeld klickt, erscheint der Kalender (sogar lokalisiert!). Wenn der Benutzer ein Datum aus wählt, wird das Textfeld automatisch mit dem Datum gefüllt. Wenn das Textfeld den Fokus verliert, verschwindet der Kalender. Beispiel 12-5: Den CalendarExtender nutzen
Abbildung 13-14: Die Unterschiede zwischen der alten und der neuen Datei
240
behavior
40
"
d i.spo.se
the
Aj"xControlToo l k 1 t . f i l teredTextBo
"
H
Ini t i..l i z e
I I / 'f�t:l241jAJA.\fut.ntna!liPdWrbSi�lft)of""'LMPx
[Ioieuoge&xOK ) [�BoxO! repräsentiert eine Grafik auf der Seite. Die Klasse Sys. Preview . UI . lmage implementiert eine ASP.NET AJAX-Version einer clientseitigen Grafik (die im DOM über das Image-Objekt repräsentiert wird). Zusätzlich zu den allgemeinen Methoden, die weiter oben in diesem Kapitel aufgeführt wurden, unterstützt die Image Klasse von ASP.NET AJAX die folgenden Eigenschaftsmethoden:
get_alternateText ( ) Ruft den Wert des alt-Attributs ab. set alternateText() Ändert den Wert des alt-Attributs. get_heightO Ruft die Höhe der Grafik ab. set_heightO Setzt die Höhe der Grafik. get_widthO Ruft die Breite der Grafik ab. set widthO Setzt die Breite der Grafik. get_imageURLO Ruft die relative oder absolute URL der Grafik ab (src-Attribut), set_imageURLO Ändert die relative oder absolute URL der Grafik (sre-Attribut). Noch einmal: Standard-DOM-Eigenschaften werden in einer Klasse gekapselt. Sie müs sen nicht viel JavaScript lernen, sondern sich nur mit den Methoden vertraut machen, die ASP.NET AJAX bereitstellt. Beispiel 14-3 zeigt, wie Sie ein leeres dmg>-Element auf einer Seite manipulieren, das anfänglich folgendermaßen aussieht:
Standardmäßig beschwert sich die XHTML-Validierung von Visual Studio über fehlende Attribute, aber wir werden JavaScript-Code verwenden, um die erforderlichen src- und alt-Attribute zu setzen. Beispiel 14-3: Das ASP.NET AJAX-lmage-Steuerelement verwenden
Controllmage .aspx < I DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitionall/EN" ''http://ww. w3. org/TR/xhtmll/DTD/xhtmll-transitional. dtd" > ASP.NET AJAX function pageLoad() { var link = new Sys. Preview.UI.Hyperlink($get( "linkl"» j link. set_navigateURl (''http://ajax. asp. net/") j var image = new Sys. Preview.UI.Image($get("Imagel"»j image. set_imageURl(" ajaxlogo. png") j image. set_alternateText("ASP.NET AJAX-logo")j
}
ASP.NET AJAX function pageLoad() { window. setlnterval( functionO { var label = new Sys. Preview. Ur. Label ($get (" Label1")) ; var textbox = new Sys. Preview.Ur. TextBox($get("TextBox1" ) ) ; label.set_text(textbox.get_text()); , } 1000); } Eingegebener Wert: Abbildung 14-7 zeigt das Ergebnis . .. ..
CSS.Klasse(n) : Abbildung 14-8 zeigt das Ergebnis.
264 I
Kapitel 14: Clientsteuerelemente
It) ASP.HIT /l.JAX - MoZllla firefox
�&lrg) ,
CSS-KlaSSe(oH!ltYlel !ltyle3 !ltylel!
fertiQ
Abbildung 14-8: Es wurden drei Styles zufällig angewandt.
Steuerelement-Event-Handling ASP.NET AJAX stattet seine Clientsteuerelemente mit einem Event-Handling-Mecha nismus aus_ Der Mechanismus arbeitet etwas anders, als Sie vielleicht erwarten würden, ist aber immer noch intuitiv. Der erste und wichtigste Schritt ist der Aufruf der initialize( )-Methode der Elemente, deren Events Sie verarbeiten wollen. Das aktiviert alle Mechanismen, die intern verwen det werden, um Events einzufangen. Dann ist die Einrichtung von Events ein Prozess, der aus zwei Schritten besteht:
1. Schreiben Sie eine Event-Handler-Funktion, die aufgerufen wird, wenn das Event eintritt. Wie beim .NET Framework erwartet die Event-Handling-Funktion zwei Argument: eines, das das Objekt enthält, das das Event abgesetzt hat, und ein zwei tes, das ein eventspezifisches Objekt aufnimmt, das, je nach Art des Events, zusätzli che Informationen zum Event enthält. 2. Knüpfen Sie die Event-Handler-Funktion mit < Element > . < Event-Name>.add« Metho
den name> ) an das Element. Die Syntax erinnert vage an die .NET Framework-Imple mentierung von Delegates.
Events tür Buttons Erinnern Sie sich an das Beispiel mit den drei modalen Pop-up-Fenstern vom Anfang dieses Kapitels? Da wurde der JavaScript-Code zur Anzeige des Fensters deklarativ im HTML-Button hinzugefügt. Das kann auch über die ASP.NET AJAX-Bibliothek erfol gen. Aber in diesem Fall gewinnen Sie nicht viel, wenn Sie ASP.NET AJAX anstelle des »reinen« JavaScript-Wegs verwenden - von der Sicherheit abgesehen, dass die ASP.NET AJAX-Bibliothek vollständig geladen worden ist, bevor JavaScript-Code an ein Element geknüpft wird. Allerdings ist es der Grundgedanke des ASP.NET AJAX-Frameworks, die serverseitige und die clientseitige Entwicklung einander anzunähern und dem Client
Steuerelement-Event-Handling I 265
neue OOP-Fähigkeiten und Browserunabhängigkeit zu verleihen. Deswegen hat es immer noch Vorteile, wenn man ASP.NET AJAX für Aufgaben verwendet, die man auch einfach mit JavaScript erledigen könnte. Beispiel 14-9 kehrt zum »Drei Fenster«-Beispiel aus Beispiel 14-1 zurück, verwendet diesmal aber ASP.NET AJAX-Event-Handling. Die HTML-Buttons werden über die Klasse Sys. Preview.UL Button referenziert, und das entsprechende Event ist (offensichtli cherweise) dick. Beispiel 14-9: ASP.NET AJAX-Button-Steuerelement-Events verwenden
ControlEventButton.aspx < I DOCTYPE html PUBLIC "-IIW3CJ/DTD XHTML 1.0 TransitionalJ/EN" ''http://www. w3. org/TR/xhtmll/DTD/xhtmll-transitional. dtd" > ASP.NET AJAX funetion pageLoad() { var textbox = new Sys. Preview.UI. TextBox($get( "TextBoxl" ) ) ; var label = new Sys. Preview.UL Label($get(" Label1"));
Abbildung 15-3: Wenn Sie auf einen Button klicken, ändert sich die CSS-Klasse des Texts. Methodenaufruf Eine Eigenschaft zu setzen ist praktisch, aber die Fähigkeit, eine Methode aufzurufen, wenn ein Event eintritt, ist eine obligatorische Funktionalität. Wie Sie wahrscheinlich erwartet haben, ist auch das in xml-script möglich. Dazu sind zwei Elemente erforder lich: •
das dnvokeMethodAction>-Element
•
das < pa rameter s>-Element
dnvokeMethodAction> unterstützt die folgenden Attribute: method Gibt die aufzurufende Methode an. target Gibt das Objekt an, dessen Methode aufgerufen werden soll. Das heißt nicht, dass Sie nur eingebaute Funktionalitäten aufrufen können. Beispiels weise können Sie die invokeMethodAction-Definition einsetzen, um eine Webservice Methode aufzurufen. Erzeugen wir eine einfache Webservice-Methode, die einen von zwei Werten zurückliefert: sty1el und sty1e2. Beispiel 15-5 enthält den Code: Beispiel 15-5: Ein Webservice, der eine zufällige CSS-Klasse zurückliefer!
Beispiel 15-5: Ein Webservice, der eine zufällige CSS-Klasse zurückliefert (Fortsetzung)
[System.Web. Script. Services. ScriptService] public class RandomCssClass : System.Web.Services .WebService { [WebMethod] public string getRandomCssClassO { Random r = new Random(); return "style" + LNext(l, 3 ); ) )
Jetzt möchten wir diesen Webservice nutzen, um ein Element anhand der CSS-Klasse zu formatieren, die auf dem Server ermittelt wird. Hier sind die beiden CSS-Klassen:
. stylel { font-family: Monospace; border-style: dotted; color: #OfO; } . style2 { font-family: Sans-Serif; border-style: solid; color: #Off; } Der erste Schritt im xml-script ist die Definition des Webservice, damit ASP.NET AJAX ihn initialisiert. Für diese Aufgabe wird das -Element verwendet. Sie geben die folgenden Attribute an:
id Eine ID, die verwendet wird, um auf diesen Webservice aus anderen Stellen des xml-script zu verweisen url Die URL des Webservice
methodName Der Name der Webservice-Methode useGet Gibt an, ob HTTP GET für den Aufruf des Webservice verwendet werden soll. Set zen Sie diese Eigenschaft auf »false« , da HTTP GET standardmäßig deaktiviert ist. < serviceMethodReq uest id="Ta ndomCs sMethod" ur1=" RandomCssClass .asmx" methodName= "getRandomCssClas s " useGet=" false" > Während Buttons beispielsweise ein click-Event absetzen können, kann eine Webser vice-Methode ein Handle für das -Event anfordern, das abgesetzt wird, wenn der Webservice seine Daten zurückliefert. Das ist ein Fall für :
Das war eine Menge Arbeit, und diese ganze Programmiererei ist sehr fehleranfällig. Wenn Sie einen Syntaxfehler im xml-script haben, merken Sie das beispielsweise daran, dass das Skript nicht funktioniert, Sie erhalten aber keine zusätzlichen Hinweise. Sie sollten also den Einsatz eines XML-Validierers in Betracht ziehen, um das xml-script zu prüfen. Beispiel 15-6 enthält den vollständigen Code, und Abbildung 15-4 zeigt das Ergebnis im Browser. Beispiel 15-6: Methoden, Webservices und Datenanbindung über xml-script aufrufen
ControlDeclarativeMethod .aspx < I DOCTYPE html PUBLIC "-IIW3C1IDTD XHTML 1.0 TransitionalllEN" ''http://ww. w3. org/TR/xhtmll/DTD/xhtmll-transitional. dtd" > ed"ratJveMethod.1
'"
�
,,""
Abbildung 15-4: Ein Klick aufden Button weist dem Label eine zufällige CSS-Klasse zu. .. ..
Obwohl der Webservice bereits im xml-script referenziert wird, müssen Sie immer noch über das ScriptManager-Steuerelement den JavaScript �' Proxy erzeugen, indem Sie die Elemente und einsetzen.
[B " �:' �.'
Datenva lid ieru ng Neben den Steuerelementen für die Datenbindung bringt das ASP.NET AJAX Futures Paket auch eigene Steuerelernente für die Validierung der Daten mit, die Benutzer einge ben. Das ist ein Feature, das viele ASP.NET-Entwickler nützlich finden. ASP.NET AJAX unterstützt die folgenden Validierer:
requiredFieldValidator Prüft, ob der Benutzer einen Wert in ein Steuerelement eingegeben hat. regexValidator Prüft die Daten in einem Steuerelement anhand eines regulären Ausdrucks, um ein bestimmtes Muster zu finden. typeValidator Prüft die Daten in einem Steuerelement anhand eines Datentyps. rangeValidator Prüft die Daten in einem Steuerelement anhand eines Wertebereichs. customValidator Prüft die Daten in einem Steuerelement anhand einer benutzerdefinierten Vali dierungsfunktion . .. ..
Wenn Sie ein UpdatePanel-Steuerelement haben, können Sie serverbasierte ASP.NET-Validierer einsetzen, um die Eingaben in den Serversteuerele �' menten zu prüfen, die sich im Panel befinden. Sie benötigen allerdings eine . aktualisierte Version dieser Steuerelernente, die mit ASP.NET AJAX kom patibel ist. Mehr Informationen finden Sie in folgendem Blog-Eintrag von Matt Gibbs: http://blogs.msdn.com/mattgi/archive/2007/05/12/validators
[B "" �:' �.'
update-available.aspx
Datenvalidierung I 287
Um Datenvalidierung zu implementieren, benötigen Sie Folgendes: •
ein zu validierendes Steuerelement
•
eine Möglichkeit, eine Fehlermeldung anzuzeigen, wenn die Validierung fehlschlägt
•
Code oder Markup zur Durchführung der Validierung
In den folgenden Abschnitten werden Sie sehen, wie man die einzelnen ASP.NET AJAX Validierer einsetzt. Dazu gehört auch, dass Sie Ihre eigene benutzerdefinierte Validierung durchführen.
Ein erforderliches Feld prüfen Die Klasse requiredFieldValidator, die prüft, ob ein Steuerelement Daten enthält, ist ein häufig verwendeter ASP .NET AJAX-Datenvalidierer. Das folgende Markup generiert ein Eingabefeld und ein Span-Element, um die Fehlermeldungen anzuzeigen, die der Validie rer generiert:
* Wie Sie sehen können, ist das Label für die Fehlermeldung per Default nicht verborgen. ASP.NET AJAX kümmert sich automatisch darum, dass es verborgen wird. Fügen Sie dem xml-script der Seite Markup für die Steuerelernente hinzu, die an der Vali dierung teilhaben - nur die Elemente für Benutzereingaben, keine Steuerelemente für die Anzeige von Fehlern. Im (validators)-Unterelement eines Eingabesteuerelements geben Sie den zu verwendenden Validierer an. Die Eigenschaft errorMessage enthält Text, der angezeigt werden soll, wenn die Validierung fehlschlägt. Der ASP.NET AJAX-Validierer unterscheidet sich allerdings von seinem ASP.NET-Gegenstück. In ASP.NET AJAX wird der Wert der Eigenschaft errorMessage als Tooltipp verwendet, der erscheint, wenn Sie den Mauszeiger über den Fehlertext halten (d.h. über das ASP.NET AJAX-Validierer Steuerelernent). Da wir gerade von Fehlertext sprechen: Es gibt kein Äquivalent für die Text-Eigenschaft von ASP.NET-Validierer-Steuerelementen. Der Fehlertext, der im Label erscheint, ist der Text, der sich bereits dort befindet. Das folgende Beispiel zeigt das xml script für die Definition eines Validierers für ein erforderliches Feld, der mit einem Text Box-Steuerelement verknüpft ist.
Der zweite Schritt ist die Verwendung des Elements (validationErrorLabel> mit den fol genden Attributen: id Die ID des Steuerelernents zur Anzeige von Fehlern associatedControl Die ID des zu validierenden Elements
288 I
Kapitel lS: Datenbindung und Validierung
Eine vollständige Seite mit Validierung wird in Beispiel 15-7 gezeigt. Beispiel 15-7: Einen Validierer für ein erforderliches Feld verwenden
ControlValidationRequiredField.aspx < ! OOCTYPE html PUBLIC "-/ /W3C1/DTO XHTML 1.0 Transitionall /EN" ''http: //www . w3. org/TR/xhtmll/DTO/xhtmll-transitional. dtd" >
< /components>
< /components>
Validierung über Programmeode Mit dem deklarativen Verfahren lässt sich gut arbeiten, aber daneben gibt es ebenfalls ein Verfahren über den Programmcode (das die Validierung im Wesentlichen zur Laufzeit hinzufügt) . Sie benötigen dafür allerdings einige Deklarationen, die so aussehen könnten:
Sie können den Validierer mit JavaScript-Code erzeugen. Es ist aber nicht so einfach her auszufinden, wie das gemacht wird. Es sind zwei Schritte erforderlich: •
Fügen Sie den Validierer hinzu: element. get_validator s( ) . add(Validierer) .
•
Nehmen Sie element.add_validated (function), wenn Sie eine Callback-Funktion verwenden wollen (eine Funktion, die aufgerufen wird, wenn die Validierung erfolgt ist).
Um auf das zu validierende Element zuzugreifen, können Sie sich keine Instanz des Steuerelements mit dem üblichen new Sys. Preview.UI.XXX-Verfahren verschaffen. Statt dessen müssen Sie folgende, etwas seltsam aussehende Syntax verwenden:
var textbox = $get("TextBoxl" ) . control; Datenvalidierung I 295
Auf clientseitige Elemente greifen Sie also zu, indem Sie das $get O-Kürzei verwenden und dann auf seine contro1-Eigenschaft zugreifen. Beispiel 15-12 zeigt eine vollständige Seite, die ein programmbasiertes Verfahren zur Validierung einsetzt. Dieses Beispiel führt die gleiche Prüfung auf ein erforderliches Feld durch, wie Sie sie in Beispiel 15-7 gesehen haben, fügt dem Textfeld den Validierer aber über JavaScript-Code hinzu. Beispiel 15-12: Einen benutzerdejinierten Validierer über Programmcode verwenden
ControlValidationCustomProgrammatic.aspx < I DOCTYPE htrnl PUBLIC "-IIW3CJJDTD XHTML 1.0 TransitionalJJEN" ''http: //WW.W3. orgJTRJxhtrnllJDTDJxhtmll-transitional. dtd" > ASP.NET AJAX function pageLoad() { var textbox = $get( "TextBoxl") .controlj validator = new Sys.Preview.UI.RequiredFieldValidator()j validator.set_errorMessage("** Geben Sie ein paar Daten ein")j textbox.get_validators().add(validator)j textbox.add_validated(validationCornplete)j ) function validationComplete(sender, args) { )
*
296 I
Kapitel lS: Datenbindung und Validierung
Beispiel 15-12: Einen benutzerdefinierten Validierer über Programmeode verwenden (Fortsetzung)
Das funktioniert natürlich auch bei komplexeren Validierern, einschließlich dem benut zerdefinierten Validierer. In diesem besonderen Fall sieht die Syntax für die Deklaration der benutzerdefinierten Validierungsfunktion folgendermaßen aus: validator .add_validateValue (validation function); Beispiel 15-13 zeigt, wie man Steuerelementen zugleich programmbasiert und deklarativ Validierer hinzufügt. Die Validerer für das erforderliche Feld und den Typ werden dekla rativ hinzugefügt, der benutzerdefinierte Validierer über Programmcode. Das Ergebnis entspricht dem, das Sie in den vorangegangenen Beispielen gesehen haben. Beispiel 15-13: Deklarative und programmbasierte Validierer verwenden
ControlValidationRequiredFieldProgrammatic.aspx < ! OOCTYPE html PUBLIC "-/ /W3C1/DTO XHTML 1.0 Transitional/ /EN" ''http: //www . w3. org/TR/xhtmll/DTO/xhtmll-transitional. dtd" > Datenvalidierung I 301
Beispiel 15-15: Die Formularübermittlung unterbinden (Fortsetzung)
Beispiel 16-3 zeigt das vollständige Beispiel, einschließlich eines anderen Panels, das etwas Dummy-Text enthält, damit wir einen Ort haben, an den wir den Posteingang zie hen können. Beispiel 16-3: Das Panel mit einer Erweiterung verschiebbar machen
DragDropExtender.aspx < I DOCTYPE htrnl PUBLIC "-//W3CJJDTD XHTML 1.0 TransitionalJJEN" ''http://ww. w3. org/TR/xhtrnllJDTD/xhtmll-transitional. dtd" > protected void Page_Load(object sender, EventArgs e) { inbox. Text new Randorn ( ) . Next(O, 100) . ToString ( ) ; =
)
ASP.NET AJAX .box { border: solid 2px black; } .mailbox { border: solid 2px black; width: 150px; } My Portal
Willkommen in Ihrem von Microsoft ASP.NET AJAX gesteuerten Portal. Das E-Mail-Statusfenster ist frei verschiebbar. Willkommen in Ihrem von Microsoft ASP.NET AJAX gesteuerten Portal Das E-Mail-Statusfenster ist frei verschiebbar. Willkommen in Ihrem von Microsoft ASP.NET AJAX gesteuerten Portal Das E-Mail-Statusfenster ist frei verschiebbar.
[...]
Sie haben zurzeit E -Mail-Nachrichten in Ihrem <
" JT,,�.___ ioj ii
rL tw..,ll>' I
•
I .
:JTypon
::" A'�'"
�""�.. 'f!.�.t.ri>ori (und erzeugen Sie ihn im (scripting>-Unterknoten des (system.web. extensions>-Knotens, falls er noch nicht besteht). Das ist besonders interessant, wenn Sie Atlas-Code zu ASP.NET AJAX migrieren, ist aber immer erforderlich.
324 I
Kapitel 17: Serverdaten verwenden
Fügen Sie jetzt das folgende Markup hinzu:
Die erste Zeile setzt die maximale Länge aller JSON-Strings während der Serialisierung. Abhängig von Ihrem jeweiligen Szenario sollten Sie hier einen größeren oder kleineren Wert wählen. Dann werden drei Konvertierer für DataSet-, DataRow- und DataTable Objekte hinzugefügt. Diese kümmern sich um die Datenobjekte, die wir verwenden wer den. Alternativ kann der Webservice so geschrieben werden, dass er ein Array mit Elementen eines benutzerdefinierten Typs enthält, der auf den Daten basiert, anstatt direkt ein Data RowCollect ion-Objekt zurückzuliefern. Der Beispiel-Webservice, den wir erstellen, ist so geschrieben, dass er die Felder AccountNumber und Name der AdventureWorks-Datenbank abfragt. Wenn Sie einen benutzerdefinierten Typen schreiben, muss dieser Typ deswegen zwei String-Eigenschaften mit den Namen AccountNumber und Name zurückliefern. Das fol gende Codefragment zeigt, wie man diesen benutzerdefinierten Typ implementieren könnte:
public class Vendor { string _AccountNumber; string _Name; public string AccountNumber { get { return _AccountNumber; } set { _AccountNumber = value; } } public string Name { get { return Name; } set
Ein ListView-$teuerelement verwenden I 32$
{ }
Name = value;
}
public Vendor(string AccountNumber, string Name) { this._AccountNumber = AccountNumber; this. Name = Name; }
}
public Vendor() { }
.. ..
Der leere Konscrukto[ public Vendor( ) { } ist erforderlich, damit die Klasse serialisierbar ist. Falls Sie diesen Klassenkonstruktor weglassen, wenn Sie �' diese Klasse in einem Webservice verwenden, erhalten Sie einen Fehler, . wenn Sie die .asmx-Datei direkt in Ihrem Browser aufrufen. Der Webservice funktioniert allerdings auch ohne und kann von Skripten aufgerufen werden. Dieser zusätzliche Konstruktor vereinfache es, den Webservice im Browser zu testen, fügt dem Skript aber keine neue Funktionalität hinzu, die erforderlich wäre.
[B " ��,.
Ein umgeschriebener Webservice, der den benutzerdefinierten Typ einsetzt, fragt die Tabelle Purchasing. Vendors aus AdventureWorks ab und wählt (in unserem Beispiel die ersten zehn) Einträge aus, genau wie es das vorangegangene Beispiel gemacht hat:
[WebMethod] public Vendor[ ] GetVendors() { SqlConnection conn = new SqlConnection( "server={local)\ \SQLEXPRESS; Integrated Security=true; Initial Catalog=AdventureWorks") ; conn.Open(); SqlCommand comm = new SqlCommand( "SELECT TOP 10 AccountNumber, Name FROM Purchasing. Vendor" , conn) ; SqlDataReader dr = corrm. ExecuteReaderO; Aber anstatt eine DataRowCollection zurückzuliefern, iteriert der Code dann über die Liste und erzeugt ein Vendor-Element für jeden Eintrag in der Datentabelle. Diese Liste wird dann in ein Array umgewandelt und vom Webservice zurückgeliefert:
List v = new List(); while (dr. Read()) { v.Add(new Vendor( dr[ "AccountNumber" ] . ToString() , dr["Name" ] . ToStringO) ) ;
326 I
Kapitel 17: Serverdaten verwenden
} return v.ToArray(); } Dieses Beispiel verwendet ein Konstrukt, das in Version 2.0 des .NET Frameworks eingeführt wurde: Generies. Um Generies zu verwenden, müssen Sie die entsprechen den Namensräume importieren (System.Collections für die List-Unterstützung und System . Collections .Generic). Beispiel 17-2 zeigt den fertiggestellten Code für eine Ver sion des Webservice, die mit dem benutzerdefinierten Typ Vendor arbeitet. Beispiel 1 7-2: Dieser Webservice liefert einen benutzerdefinierten Typ.
ListViewVendorsCustom.asmx using using using using using using using using
public class Vendor { string _AccountNumber; string _Name; public string AccountNumber { get { return _AccountNumber; } set { _AccountNumber = value; } } public string Name { get { return Name; } set { _Name = value; } }
Ein ListView-$teuerelement verwenden I 327
Beispiel 1 7-2: Dieser Webservice liefert einen benutzerde{inierten Typ. (Fortsetzung)
)
public Vendor(string AccountNumber, string Name) { this._AccountNumber = AccountNumber; this._Name = Name; ) public VendorO { )
[WebService (Namespace = ''http://hauser-wenz. deI" ) ] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfilel_l) ] [System.Web.Script. Services.ScriptService] public class Vendors : System.Web.Services.WebService { [WebMethod] public Vendor[ ] GetVendors() { SqlConnection conn = new SqlConnection( "server= (local) \ \SQLEXPRESS; Integrated Security=true; Initial Catalog=AdventureWorks"); conn.Open(); SqlCommand comm = new SqlCommand( "SELECT TOP 10 AccountNumber, Name FRQM Purchasing. Vendor" , conn); SqlDataReader dr = comm.ExecuteReader(); List v = new List(); while (dr.Read()) { v.Add(new Vendor( dr[ "AccountNumber" ] . ToString() , dr[ "Name"] . ToString() ) ) ; )
return v .ToArray(); )
) 11 .
Im Quellcode-Paket für dieses Buch sind die beiden Varianten des Web service - einer, der DataRow(ollection verwendet, und einer, der einen �' benutzerdefinierten Typ verwendet - als ListViewVendors.asmx und ListViewVendorsCustom.asmx enthalten. Sie können beide für die fol genden Beispiele verwenden. Sie sind austauschbar.
Gil "·: �:' �.'
.
Jetzt zurück zur ASP.NET-Seite, von der der Webservice aufgerufen wird. Webservices wurden in Kapitel 5 ausführlicher behandelt, deswegen sollen Sie hier nur kurz daran erinnert werden, was Sie tun müssen, um sie zu verwenden. Erst muss die .asmx-Datei im xml-script referenziert werden. Dann wird ein clientseitiges Proxy generiert: ein loka les Objekt, das das Verhalten des entfernten Webservice bereitstellt. Das bedeutet, dass
328 I
Kapitel 17: Serverdaten verwenden
das lokale Objekt die gleichen Methoden wie der entfernte Webservice hat. Ein Aufruf der lokalen Methoden ruft seinerseits die entfernten Methoden auf. Dieser Aufruf erfolgt asynchron (wie die XMLHttpRequest-Aufrufe, die in Kapitel 3 durchgeführt wurden). Eine Callback-Funktion wird verwendet, um die Ergebnisse des Aufrufs zu verarbeiten, nach dem der Webservice Daten zurückliefert. Aber achten Sie beim Schreiben des ASP.NET AJAX-ScriptManager-Steuereiements darauf, dass Sie eine Referenz auf die .asmx-Datei des Webservice einschließen. Hier ist das erforderliche Markup:
Wenn die Seite geladen wurde, müssen Sie den Webservice aufrufen. Allerdings ist die Phrase »Wenn die Seite geladen wurde« etwas irreführend. Der folgende Code würde bei spielsweise nicht funktionieren:
window.onload = function( ) { Vendors.GetVendors(callComplete); } Das load-Event einer HTML-Seite wird ausgelöst, wenn das HTML der Seite vollständig geladen ist. Aber zu diesem Zeitpunkt kann es sein, dass die ASP.NET AJAX-Bibliothek und der Webservice-Proxy noch nicht vollständig geladen worden sind. Deswegen würde dieser Code mit einer JavaScript-Fehlermeidung wie »Vendors is not defined« fehlschla gen. Daher ist es besser, wenn man eine Verzögerung einbaut. Sie könnten die window.setTimeout( )-Methode von JavaScript einsetzen oder warten und den Benutzer auf einen Button klicken lassen, um die Daten abzurufen. Dazu könnten Sie eine Syntax wie die folgende verwenden (die Funktion loadVendors( ) wird im nächsten Schritt imple mentiert):
Das beste Mittel ist die Verwendung der speziellen page Load ( )-Methode, die ASP.NET AJAX bereitstellt:
function pageLoad() { Vendors.GetVendors(callComplete); } Anschließend können Sie den Webservice aufrufen:
function loadVendors() { Vendors.GetVendors(callComplete, callError); }
Ein ListView-$teuerelement verwenden I 329
Sie erhalten dann die Ergebnisse in der ersten Callback-Funktion (oder einen Fehler in der zweiten). In der Callback-Funktion müssen Sie dann Folgendes tun:
1 . Sie müssen sich eine Referenz auf das Element holen, das Sie nutzen wollen, um die Daten anzuzeigen (im Beispiel ist das < div id="output" I» . 2. Sie müssen auf seine control-Eigenschaft zugreifen und seine set_data( )-Methode aufrufen, um die Ergebnisse des Webservice-Aufrufs zu übermitteln. Das führt zu folgendem Code:
function callComplete(result) { $get ("output" ) . contral. set_data (result); } Jetzt wird es noch etwas schwieriger: Sie müssen das xml-script-Markup erstellen. Der Anfang ist einfach: Erzeugen Sie ein -Element, und betten Sie ein -Element und dann ein -Element ein:
< page xmlns=" http: //schemas .microsoft . com/xml-script/200S" > < /components> Jetzt können Sie in das -Element platzieren. Dieses Element braucht einige Attribute:
itemTemplateParentElementld Die ID des Elements, das das Elternelement der Elemente für die einzelnen Daten elemente ist. Das klingt etwas verwirrend, meint aber eigentlich nur das
-Ele ment im Beispiel. id Die ID des Elements, in das das Ergebnis geschrieben wird Das folgende Markup ist das Ergebnis unseres Beispiels mit der ungeordneten Liste:
Im -Element müssen die Layout-Vorlage und die Elementvorlage definiert werden. Ersteres ist einfach - Sie müssen einfach nur das äußere referenzieren:
dayoutTemplate>
330 I
Kapitel 17: Serverdaten verwenden
Das dtemTemplate> ist etwas komplizierter. Diesmal müssen Sie das Element für die ein zelnen Daten referenzieren. Im Beispiel ist dies das
-Element.
dtemTemplate>
Im -Element müssen Sie die Bindungen für alle Elemente definieren. Da Sie Text ausgeben wollen, können Sie das -Element verwenden, das eine Repräsenta tion des Label-Websteuerelements von ASP.NET AJAX ist. Im Markup-Code sind die beiden folgenden Eigenschaften erforderlich: dataPath Der Name der Klasseneigenschaft, die gebunden werden soll property Die Eigenschaft des Label-Steuerelements, an die die Daten gebunden werden sollen Das führt zu folgendem Markup:
Das ist eine Menge Arbeit und leider ohne jegliche IntelliSense-Unterstützung. Aber das Ergebnis ist lohnenswert. Der letzte Schritt ist das Laden der PreviewScript.js-JavaScript Bibliothek aus dem Futures-Paket. Diese Bibliothek enthält die eigentliche Clientfunktio nalität:
Ein ListView-$teuerelement verwenden I 331
Beispiel 17-3 zeigt den vollständigen Markup- und Skriptcode für die Seite. Beispiel 1 7-3: Daten an eine HTML-Liste binden
ListViewUnorderedList.aspx < I DOCTYPE html PUBLIC "-IIW3CJ/DTD XHTML 1.0 TransitionalJ/EN" ''http://ww. w3. org/TR/xhtmll/DTD/xhtmll-transitional. dtd" > ASP.NET AJAX function loadVendors() { Vendors. GetVendors(callComplete, callError); )
Beispiel 1 7 7: Daten von einer benutzerdefinierten Datenquelle anzeigen (Fortsetzung) -
< Icomponents> Es ist also keine wirkliche Programmierarbeit erforderlich (außer für den DataService Webservice), sondern nur Deklarationen. Die Ausgabe zeigt die ersten zehn Elemente in der Tabelle Purchasing. Vendors als HTML-
-Element formatiert. Deswegen ist die Ausgabe dieses Skripts mit der in Abbildung 17-2 identisch.
Daten verwalten Die Anzeige von Daten ist nur der erste Schritt. Die logische Konsequenz wäre eine Imple mentierung der anderen Methoden, die in System.CornponentModel.DataObjectMethodType definiert sind. Dann können Sie Daten seitenweise durchblättern, Daten aktualisieren und mehr und würden sich damit eine ganze Welt neuer Möglichkeiten eröffnen. Aber Sie würden eine bessere Leistung erzielen und effizienter entwickeln können, wenn Sie das ASP .NET-Steuerelement GridView (oder ein beliebiges anderes geeignetes Daten-Steuerele ment) verwenden würden. Wenn Sie sich Gedanken über die Postbacks und Seitenaktual isierungen machen, die für dieses Steuerelement so entscheidend sind, werfen Sie einen Blick in Kapitel 6. Dort werden Sie lernen, wie Sie diese Beschränkung - natürlich unter großem Einsatz von ASP.NET AJAX - überwinden können.
Zusammenfassung Dieses Kapitel hat Ihnen gezeigt, wie Sie vom Client auf serverseitige Daten zugreifen: Implementieren Sie einfach einen Webservice, und nutzen Sie dann die Datenbindungs möglichkeiten von ASP.NET AJAX und besondere Clientsteuerelemente wie ListView, um die Informationen vom Server anzuzeigen.
Zum weiteren lesen hup:1Iquickstarts. asp. "etlFutureslajaxldoddatao aspx Vorab-Dokumentation von Microsoft zum Einsatz von Datendiensten aus ASP.NET AJAX
hup:1Iastoria. rnslivelabs. corni Microsoft-Projekt mit dem Codenamen »Astoria«, das versucht, es Anwendungen zu ermöglichen, Daten als Datendienst zu veröffentlichen
Zusammenfassung I 343
KAPITEL 1 8
Entfernte Webservices nutzen
In den Kapiteln 5 und 17 haben wir behandelt, wie man ASP.NET-Webservices mit ASP.NET AJAX nutzt. Das XMLHttpRequest-Objekt, das alle Ajax-Anwendungen antreibt, läuft in einer Browser-Sandbox, die verhindert, dass auf irgendetwas zugegriffen wird, das sich außerhalb der aktuellen Domain befindet. Wenn Sie auf Daten von einem ent fernten Webservice (einem, der sich auf einem anderen Server befindet) zugreifen müs sen, gibt es also nur eine Lösung: Erzeugen Sie auf Ihrem Server einen Proxy, und rufen Sie diesen Proxy dann aus Ihrem JavaScript-Code auf. Das erlaubt Ihnen dann die Erstel lung von Mashups: Das sind Webanwendungen, die Daten aus unterschiedlichen Quel len nutzen, um sie zu etwas Neuem »zusammenzumischen« , Dieses Kapitel zeigt Ihnen, wie Sie einen entfernten Webservice für JavaScript zugreifbar machen. Dann können Sie JavaScript nutzen, um mehrere externe Quellen zu etwas Neuem zu kombinieren. Die gute Nachricht: Die ASP.NET Futures bieten eine eingebaute Unterstützung für Pro xies für solche Webservice-Aufrufe, nämlich eine Technologie, die als Webservice-Bridge bezeichnet wird. In den folgenden Abschnitten werden wir Seiten erstellen, die Daten von den beiden beliebtesten kommerziellen Webservices abrufen: dem Google-Such Webservice und dem Amazon-E-Commerce-Webservice. Die hier gezeigten Techniken können leicht an jeden anderen SOAP-Webservice angepasst werden. Das Geheimnis hinter dieser Technik liegt in der neuen Dateinamenserweiterung, die die Website-Vorlage des ASP.NET AJAX Futures-Pakets in Web.config registriert: .asbx. Dateien mit dieser Erweiterung können XML-Markup enthalten, das Informationen zu einer lokalen (serverbasierten) Proxy-Klasse für einen Webservice enthält. Der Java Script-Code der Webseite stellt nur eine Verbindung mit der .asbx-Datei her, die sich dann um die Kommunikation mit dem entfernten Webservice kümmert. Abbildung 18-1 zeigt diesen Mechanismus.
Wenn Sie die Website-Vorlage des ASP.NET AJAX Futures CfPs nutzen, ist die Web.config-Datei bereits vorbereitet. Allerdings enthalten sowohl das Januar 2007-, das Mai 2007- als auch das Juli 2007-Release der ASP.NET AJAX Futures einen Bug, der sich in der folgenden Zeile befindet:
Abbildung 18-1: Die C/ientseite ruft die Serverbridge auf, und diese ruft den entfernten Webservice auf Das *-Zeichen ist hier falsch. Unglücklicherweise bemerkt man diesen Fehler nicht sofort, sondern erst später, wenn einem irgendein Skript mitteilt, dass »There is no build provider registered fOT the extension '.asbx'.« . Die folgende Version funktioniert:
Nehmen Sie die Korrektur an all Ihren Websites vor, die sich auf Features aus den ASP.NET Futures stützen. Sie benötigen diese Korrektur auch für alle futuresbasierten Websites, die Sie erstellen. (Alternativ können Sie die Web.config-Dateivorlage ändern, damit neue Sites die Korrektur bereits haben. Die Vorlagen für Web.config-Dateien befinden sich am ASP.NET Futures-Installationsort. Das ist standardmäßig %program
dir%lMicrosoft ASP.NET\ASP.NET Futures July 2007\vl.2.61 0251web_config.
Den Google-Webservice nutzen Der Google-Webservice bietet bequemen, programmgesteuerten Zugriff auf die Suchma schine und verwendet dazu eine SOAP- und eine REST-Schnittstelle. In unserem Beispiel werden wir die SOAP-Schnittstelle für die ASP .NET AJAX-Webservice-Bridge verwen den. Wenn Sie den Google-Webservice verwenden möchten, müssen Sie sich bei Google regis trieren. Um die Anfrage durchzuführen, gehen Sie zu http://www.google.com/apis/ soapsearch. Google sendet Ihnen daraufhin einen 32-Byte-Lizenzschlüssel, den Sie benö tigen, um Daten mit jeder Suchanfrage an den Dienst zu senden.
Als dies geschrieben wurde, hatte Google zumindest vorübergehend die Ausgabe neuer Lizenzschlüssel eingestellt. Wenn Sie bereits einen Schlüs sel haben, können Sie den Webservice weiterhin verwenden. Sollten Sie keinen Lizenzschlüssel haben, machen Sie sich keine Sorgen. Der Abschnitt »Den Amazon-Webservice nutzen(( entwickelt zwei Beispielan wendungen, für die weiterhin Lizenzschlüssel ausgegeben werden.
Den Google-Webservice nutzen I 345
Manuelle .asbx-Registrierung Wenn Sie den .rnsi-ASP.NET AJAX-Installer nicht ausführen können, wird die .asbx Erweiterung nicht auf Ihren Webserver abgebildet. Führen Sie in diesem Fall die 115Managementkonsole aus, und ordnen Sie die .asbx-Dateierweiterung der Datei aspnecisapi.dll zu, und erlauben Sie die HlTP-Verben GET, POST und HEAD. Und fügen Sie der web.config-Datei jeder Website, die eine Webservice-Bridge nutzt, folgendes Markup hinzu: Wenn Sie den IlS 7 nutzen, müssen Sie dem -Unterknoten des -Element im -Element bleibt gleich, da sich die Parameter nicht ändern. Es wird allerdings ein neues -Ele ment eingeführt, das die beiden Transformierer angibt. Für den XSLT-Transformierer
360 I
Kapitel 18: Entfernte Webservices nutzen
müssen Sie natürlich die zu verwendende XSL-Datei angeben. Beispiel 18-9 zeigt das XML-Markup für die aktualisierte Bridge-Datei. Beispiel 18-9: Die aktualisierte (XSLT-)Webservice-Bridge für den Google-Webservice
Cameron 1,lcKenZie: Whal is WebSphere? Java, J2EE, Portal and B eyond! (Demyslifying lBI.l's !.iiddle Tier
TedlnoloQY, Vo l l )
Nldlolas C. Zakas: Professional Ajax. 2nd Edition (Programmer 10 Programmer) • Dave Crane: Ajax in Action • J eremy Kei!tl: Bullelprool Ajax (Voices Thai Matter) • Bill Evjen: Professional ASP.NET 2.0 Spedal Edition (Wrox Professional Guides) • Cristian Darie: AJM and PHP Buildin g Responsive Web Appl lcallo n s • Prabhakar Chaoanli: Google Web Toolki!: GWTJava Aiax Programmlno
•
•
Dave Crane: Prototype and Scriptaculous in Action
• Scott Raymond Ajax on Rails
Abbildung 18-5: Den Amazon-Katalog mit einer ASP.NET AJAX-Bridge und einer XSL Transformation durchsuchen
Den Yahoo!-Webservice (und REST und XPath) nutzen Im letzten Beispiel in diesem Kapitel werden wir noch einen weiteren Webservice nutzen, diesmal den Yahoo!-Webservice, Dieser Webservice bietet aktuell keine SOAP-Schnitt stelle, sondern nutzt REST. Das steht für » REpresential State Transfer« und ist ein Konzept aus Roy Fieldings Dissertation (Fielding ist einer der Autoren der HTTP-Spezifikation). Im Rahmen unseres Beispiels ist die gesamte Geschichte von REST nicht so relevant. Wir müs sen nur wissen, dass REST-Webservice-Aufrufe in der Regel auf folgende Weise funk tionieren: Es wird eine GET -Anfrage (!) an den Server gesendet, bei der alle Anfragedaten (die aufzurufende Methode, die zu übergebenden Argumente) Teile der URL sind. Die Rückgabedaten aus diesem GET-Aufruf sind üblicherweise XML, können aber auch in anderen Daten übertragen werden, beispielsweise als Klartext, CSV oder JSON. Deswegen müssen wir auf dem Server eine GET-Anfrage statt einer POST-SOAP-Anfrage senden. Das ASP,NET AJAX Futures-Paket bietet Unterstützung dafür. Aber zunächst müssen Sie sich bei Yahoo! registrieren, damit Sie den Dienst verwenden können. Yahoo! erwartet, dass Sie sich für alle Anwendungen registrieren, und bietet deswegen verschiedene Schlüssel, wenn Sie mehrere nutzen wollen. Um eine solche Anwendungs ID anzufordern, gehen Sie zu http://search.yahooapis.com/webservices/register_ applica tion. Sie müssen sich bei Yahoo! anmelden, um auf diese Seite zuzugreifen. Wenn Sie
366 I
Kapitel 18: Entfernte Webservices nutzen
noch kein Yahoo!-Konto haben, können Sie sich kostenlos registrieren. Dann wird Ihnen der Fragebogen aus Abbildung 18-6 präsentiert, indem Sie Hintergrundinformationen über die Anwendung angeben müssen. Dann zeigt Ihnen die Webseite in Abbildung 18-7 das Ergebnis, einschließlich des Anwendungsschlüssels. t) Regllior your .pp hcotron on tho Yahool Dovolopor Nolwork
r "duc< CO " ..
...., y,hoo' 'nobi•• w.b �p,'
: MyYahool RESTS�MC. D�mo
, _ _ _ j"http ://dom.'n, Wie in den vorangegangenen Beispielen wird mit dem -Element eine Methode definiert. Die beiden Argumente appid und output kommen vom Server, aber das Abfra geargument (der eigentliche Suchbegriff) wird durch den JavaScript-Code gestellt:
-Element können Sie jetzt auf bestimmte Knoten und Eigenschaften aller Ergebnisse zugreifen. In diesem Beispiel inte ressieren wir uns für den Titel und die URL der Suchergebnisse, die durch die Elemente und angezeigt werden. Das folgende Markup wählt diese Elemente aus und stellt auch die JavaScript-Eigenschaftsnamen für sie: resultTitle und resultUrl:
Beispiel 18-15 zeigt das vollständige Markup für die Bridge. Beispiel 18-15: Die Webservice-Bridge für den Yahoo! REST-Webservice
Yahoo.asbx Nachdem die Bridge eingerichtet ist, ist der Rest der Anwendung »business as usual« und den vorangegangenen Beispielen sehr ähnlich. Erzeugen Sie eine ASP.NET-Datei, und referenzieren Sie die .asbx-Datei und das Futures-Paket im ScriptManager-Steuereiement:
Fügen Sie dann ein UI hinzu, über das Benutzer einen Suchbegriff eingeben können. Nachdem auf den Absenden-Button geklickt worden ist, muss dieser Code ausgeführt werden:
function Search() { var query = new Sys. Preview.UI.TextBox($get( ' Query' ) ) $get("Button" ) .disabled = true; clearListOj
In der Funktion callCompleteO werden die Ergebnisse des Webservice-Aufrufs automa tisch als erstes Argument angegeben. Dieses Argument ist ein JavaScript-Array mit allen Suchergebnissen (der Yahoo!-Webservice liefert standardmäßig zehn Ergebnisse, es sei denn, es wurden wenigerTreffer gefunden). Jedes dieser Array-Elemente ist ein Objekt mit
Den Yahoo!-WebseMce (und REST und XPath) nutzen I 371
den Eigenschaften resultTitle und resultUrl, die in der Bridge-Datei angegeben wurden. Dann ist es ziemlich einfach, diese Daten zu nutzen und auf die Seite anzuwenden:
function ca11Comp1ete(resu1t) { for (var i = 0; i < result.1ength; i++) { var li = document.createElement("li"); var a = document.createElement( "a"); a . setAttribute( "href", resu1t [i]. resu1tUr1); a .innerHTML resu1t[i] .resu1tTit1e; =
} $get("Button" ) .disabled = fa1se; } Beispiel 18-16 zeigt den vollständigen Code für dieses Beispiel. Die Suchergebnisse kön nen Sie in Abbildung 18-9 sehen (beachten Sie den hohen Rang der ASP.NET AJAX Homepage bei einer Suche nach »Ajax« ;-» . Beispiel 18-16: Den Yahoo!-REST-Webservice au.frufen
Yahoo.aspx < I DOCTYPE htm1 PUBLIC "JJW3C1 JDTD XHTML 1.0 TransitionalJJEN" ''http://www.w3.org/TR/xhtm11/DTD/xhtml1transitional. dtd") (tit1e>ASP.NET AJAX (script language=" JavaSeript" type= "text! javascript" > function clearList() { $get (" Results") . innerHTML = } function Search() { var query = new Sys. Preview.UI.TextBox($get( 'Query ' » ) $get("Button").disab1ed = true; clearList(); ORei11y.AspNetAJAX.Yahoo.Search( { "query" : query.get_textO } , ca11Comp1ete, ca1lError ); } function ca11Comp1ete(resu1t) { for (var i = 0; i ( resulL1ength; i++) { var li = document.createElement("li"); var a = document.createElement( "a"); a. setAttribute(" href", resu1t [i]. resu1tUr1); a . innerHTML = result[ i ] .resu1tTitle; 1i.appendChi1d(a) ;
372 I
Kapitel 18: Entfernte Webservices nutzen
Beispiel 18-16: Den Yahoo!-REST-Webservice aufrufen (Fortsetzung)
function pageLoadO { var ani = new Sys.Preview.UI.Effects.NumberAnimation()j ani. set_target($get("label1") . control) j ani.set startValue(o)j ani.set endValue(300)j
382 I
Kapitel 19: Animationenverwenden
Beispiel 19-3: Ein Element mit einer Animation verschieben (Fortsetzung) ani.set duration(3)j ani. set_integralValues(true)j ani.setValue function(value) { Sys.UI.DomElement. setlocation( this.get_target().get_element(), value, value)j ) ani. playO j =
)
Schau, wie ich mich bewege . . . < Icomponents> Nachdem die Seite geladen wurde, wandert das label-Element in einem 45-Grad-Winkel über die Seite. Beachten Sie, wie die CSS-Eigenschaft position: relative eingesetzt wird, um das zu ermöglichen - Sie müssen die Position nicht setzen. Abbildung 19-2 ist eine Momentaufnahme des Ergebnisses.
Eine length-Animation einsetzen, um ein Element zu bewegen Der vorherige Code kann auch deklarativ geschrieben werden. Wie bereits angemerkt wurde, dürfen die Eigenschaften top und left nicht nur eine Zahl enthalten, sondern müssen auch eine Einheit einschließen, wenn der Code browserübergreifend sein soll. Die Klasse NumberAnimation kann die Einheit nur angeben, wenn Sie eine benutzerdefi nierte setValue( )-Methode erzeugen. ASP.NET AJAX bietet allerdings auch eine Klasse namens LengthAnimation, die in der Lage ist, diese Aufgabe direkter durchzuführen.
Eine Animation verwenden, um einen Fade-Effekt zu erzeugen I 383
\:) ASP.HIT AJ AX · Mozilla Flrefox
�rg)rg]
Abbildung 19-2: Das Element bewegt sich über die Seite. Sie funktioniert wie NumberAnimation, es gibt aber zwei Unterschiede: •
Die Werte für alle Animationsschritte werden immer gerundet.
•
Der Wert der Eigenschaft unit (der Default ist " px") wird an den numerischen Wert angehängt.
Die Klasse LengthAnimation scheint also ein »besseres« Mittel zur Bewegung eines Ele ments zu sein als die im obigen Beispiel verwendete Klasse NumberAnimation. Aber es funktionieren beide, und deswegen werden beide hier gezeigt. Trotzdem ist es etwas verzwickt, wenn man die Klasse LengthAnimation verwendet, um ein Label-Steuerelement zu animieren. Die Eigenschaften left und top sind Teil des Styles des Elements, auf den nicht direkt über Eigenschaften zugegriffen werden kann. Es gibt aber ein Verhalten namens ASP.NET AJAX Schau, wie ich mich bewege . . . 386 I
Kapitel 19: Animationenverwenden
Beispiel 19-5: : Animationen auf einer Seite gruppieren (Fortsetzung)
< /components> Diese gruppierte Animation besteht aus drei einzelnen Animationen, die alle zur gleichen Zeit abgeschlossen werden (siehe Abbildung 19-3):
1. Das Element verblasst.
2.
Das Element wird nach rechts bewegt.
3. Das Element wird nach unten bewegt. Eine Animation verwenden, um einen Fade-Effekt zu erzeugen
387
\:) ASP.HIT AJ AX · Mozilla Flrefox
�rg)rg]
Abbildung 19-3: Das Label bewegt sich und verblasst gleichzeitig. Auch wenn die praktische Verwendung von Animationen etwas eingeschränkt ist, macht ASP.NET AJAX es sehr leicht, eine Webanwendung zu einem kleinen Augenschmaus zu machen. Da all diese Features in einer externen JavaScript-Datei gebündelt werden, wird die PreviewScript.js-Bibliothek selbst nicht dadurch aufgeblasen, dass diese Funktionali tät standardmäßig darin eingeschlossen ist.
Zusammenfassung Die ASP.NET AJAX Futures bieten mehrere Animationen, die verwendet werden kön nen, um Elemente zu animieren oder zu verändern. Diese Animationen können pro grammgesteuert und deklarativ angewandt werden und bieten so maximale Flexibilität bei der Entwicklung.
Zum weiteren Lesen hup://blogs.msdn.com/phoniroj/orchive/2007/03/15/howto-sys-preview-ui-effects-fadeoni mation.aspx Ein Blog-Eintrag zu FadeAnimation
388 I Kapitel 19: Animationenverwenden
KAPITEL 20
lesezeichen, Zurück- und Vor-Button reparieren
Gegenüber »klassischen« Webanwendungen haben Ajax-Anwendungen eine Reihe von Vorteilen. Allerdings dürfen auch die Nachteile des Konzepts nicht ignoriert werden. Mangel Nummer 1 ist natürlich, dass JavaScript und ein ziemlich moderner Browser erforderlich sind, was zwischen 5% und 10% der Benutzer ausschließt. Oe nach Zielpu blikum kann diese Zahl sich erheblich ändern.) Außerdem brechen die meisten Ajax Anwendungen mit zwei Kernelementen des Webs: der Unterstützung für Browser-Lese zeichen (»Favoriten« im Internet Explorer) und der Unterstützung für die Zurück- und Vor-Buttons im Browser. Mit derartigen Traditionen zu brechen wird nicht nur als unhöflich betrachtet, sondern hat in der Regel auch Folgen. Als Live.com in 2006 gestartet wurde, nutzte der Suchma schinenteil eine Menge Ajax-Effekte - und hat damit tatsächlich den Zurück-Button unbrauchbar gemacht. Nach einem öffentlichen Aufschrei wurde ein paar Tage später Unterstützung für den Zurück-Button ergänzt. Diese brauchte eine Menge JavaScript und löste im Internet Explorer einige Klickgeräusche aus (da in einigen Szenarios Informationen aus einem versteckten Frame neu geladen wurden). Das führte zu weiterer öffentlichen Entrüstung und in der dritten Version wurde die zusätzliche Funktionalität endgültig entfernt. Mittlerweile arbeitet Live.com wie erwartet, mit Lesezeichenunter stützung und funktionierenden Vor- und Zurück-Buttons. Der Grund für die fehlende Lesezeichenunterstützung ist der Umstand, dass Ajax Anwendungen sich alle Mühe geben, eine vollständige Aktualisierung der Seite zu ver meiden. Deswegen ändert sich eventuell der Zustand einer Seite, aber nicht die URL. Es ist deswegen nicht möglich ein Lesezeichen für eine Ajax-gesteuerte Seite zu erstellen, da der Zustand der Seite nicht Teil der URL ist. Eine Folge ist, das die Vor- und Zurück-But tons in einem Webbrowser ebenfalls nicht funktionieren. Sie können nur zwischen URLs navigieren. Keine neue URL führt zu keinem neuen Eintrag im Verlauf (Firefox: Chronic) des Browsers, und deswegen ist keine Navigation möglich. Diese beiden Probleme sind also miteinander verwandt, und ihre Lösungen sind ebenfalls ähnlich. Der Grundgedanke ist, dass jedes Mal die URL geändert wird, wenn sich der Zustand der Seite ändert. Aber in den meisten Fällen führt eine Änderung der URL zu
I 389
einem Neuladen der Seite, genau dem Effekt also, den wir ursprünglich eigentlich ver meiden wollten. Die einzige Ausnahme ist eine Änderung des Hashs einer URL. Wenn die aktuell geladene Seite Page.aspx ist und JavaScript-Code das in Page.aspx#anyData ändert, erfolgt kein Neuladen (allerdings scrollen einige Browser das Dokument an den Anfang, ein Effekt, der sehr schwer zu vermeiden ist).
Mit Code reparieren Die zuvor beschriebene Problemquelle (keine Änderung der URL) führt zu einer einfa chen Lösung für das Lesezeichenproblem: Jedes Mal, wenn sich der Zustand der aktuel len Seite ändert, werden diese Zustandsinformationen in den Hash der aktuellen Seite gesteckt. Jedes Mal, wenn eine Seite geladen wird, werden eventuell vorhandene Daten aus dem Hash der URL auf die Seite angewandt und so der Zustand der Seite wiederher gestellt, der bestand, als die Seite geladen wurde. Es sind also zwei Teile JavaScript-Code erforderlich: Jedes Mal, wenn sich etwas auf der Seite ändert, müssen diese Informa tionen in den Hash gesteckt werden, wie es im folgenden Pseudo-Code gezeigt wird:
function somethingChangedO { location.hash = "#" + getCurrentpageState(); } Das zweite Stück Code wird ausgeführt, wenn die Seite zum ersten Mal geladen wird. Gibt es Zustandsinformationen im Hash? Wenn ja, müssen diese auf die aktuelle Seite angewandt werden:
function pageLoad() { if (location.hash. length 0) { applyPageState(location.hash); } } )
Im Grunde müssen Sie also nur die Funktionen getCurrentPageStateO und applyPage StateO implementieren, und das kann ein ziemliches Hindernis sein. Die größte Heraus forderung ist häufig die Serialisierung des aktuellen Seitenzustands und seiner Speicherung in der URL sowie die Frage, wie er wieder auf die Seite deserialisiert wird. Deswegen gibt es keine allgemeine Lösung - nur das Verfahren für die Lösung des Prob lems ist immer das gleiche. Die Reparatur der Unterstützung für die Vor- und Zurück-Buttons ist allerdings deutlich komplizierter. Hier verhalten sich Browser ziemlich unterschiedlich. Mozilla-Browser erzeugen automatisch einen Verlaufseintrag, wenn sich der URL-Hash ändert. Denken wir uns eine Ajax-Anwendung, die folgende URLs aufgrund von Aktionen des aktuellen Nutzers lädt: Page.aspx#l, Page.aspx#2 und Page.aspx#3. Wenn aktuell Page.aspx#3 geladen ist und der Benutzer auf den Zurück-Button klickt, lädt der Brow ser Page.aspx#2. Aber tatsächlich ändert sich nur die URL, ohne dass die Seite neu gela den wird, und die Funktion pageLoad() wird nicht ausgeführt. Es muss also noch regelmäßig die URL darauf geprüft werden, ob neue Informationen hinzugefügt wurden. Ist das der Fall, müssen die neuen Informationen wieder auf die Seite angewandt werden.
390 I Kapitel 20: Lesezeichen, Zuruck- und Vor-Button reparieren
Sicherheitslöcher mit lesezeichen Ein Verfahren zur Serialisierung von Seitenzuständen auf das ich in Sicherheitsprufungen häufig stoße, ist die Verwendung von ]SON. Einige Webseiten, die so verantwortungsbe wusst, dass sie sich um die Lesezeichenunterstützung kümmern, serialisieren den Seiten zustand, indem Sie Seitene1emente und ihre Werte in einen JSON-String wie diesen schreiben: {"TextBoxl" : "My Data", "LabeIl": "Same other data", "DropOownListl": "2n } Diese Daten werden dann URL-codiert (mit Hilfe von JavaSeripts escape( )-Funktion) und schließlich an die URL angehangen. Bisher gibt es keine Probleme mit diesem Verfahren. Das Problem setzt allerdings ein, wenn es darum geht die Daten aus der URL wieder in die Seite zu integrieren. Das einfachste Verfahren, um den JSON-String wieder in ein Java Script-Objekt zu konvertieren, ist es, JavaSeripts eva lO-Funktion auf folgende Weise zu verwenden: var 0 = eval("(" + location.hash. substring(l) + " ) " ); Denken Sie einen Augenblick über diesen Code nach: Daten aus der URL werden als Java Script-Code ausgewertet. Das ist das klassische Beispiel für Cross-Site Scripting (XSS) und offensichtlich sehr gefährlich. Ein bösartiger Angreifer könnte gefährlichen JavaScript Code aufbauen, ihn an die URL der Seite anhängen und diese URL dann an Opfer senden. Jeder Empfänderder URL, der auf sie zugreift, würde den JavaScript-Code dann in seinem Browser ausführen. Ziehen Sie deswegen immer in betracht, dass die URL-Informationen manipuliert sein könnten. Stecken Sie keine schützenswerten Informationen in die URL und seien Sie besonders vorsichtig, wenn Sie diese Informationen wieder auf die Seite anwenden.
Für den Internet Explorer sind einige zusätzliche Schritte erforderlich. Der Microsoft Browser erzeugt nur dann einen Verlaufseintrag, wenn eine HTTP-Anfrage erzeugt wurde. Eine Änderung des URL-Hashs bewirkt keine solche Anfrage - und wir wollen diese Anfrage auch nicht, wir versuchen schließlich zu vermeiden, dass die Seite neu gela den wird. Es gibt aber einen Workaround. Wenn eine Seite einen internen Frame (interne Frames werden aufgrund des Namens des verwendeten HTML-Elements, , auch IFrame genannt) verwendet und dieser interne Frame eine HTTP-Anfrage erzeugt, wird diese HTTP-Anfrage in den globalen Browserverlauf der äußeren Seite geschrieben. Das führt direkt zu einer möglichen Lösung für das Vor/Zurück-Button-Problem: Wenn JavaScript-Code den Internet Explorer entdeckt, wird dynamisch ein < iframe>-HTML Element erzeugt und an die Seite angehängt. Dieser IFrame wird mit CSS unsichtbar gemacht, da wir keine visuellen Effekte von dem IFrame brauchen. Jedes Mal, wenn sich der Zustand der Seite ändert, wird jetzt im IFrame eine neue Seite geladen, und das erzeugt einen neuen Eintrag im Browserverlauf. Wenn der Benutzer dann auf den Vor- oder Zurück-Button des Browsers klickt, lädt der IFrame die vorange-
Mit (ode reparieren I 391
gangene oder nachfolgende Seite. JavaScript-Code entdeckt dann, dass eine neue Seite geladen wurde, und wendet den erforderlichen Seitenzustand an. Der JavaScript-Code, der für diesen Hack benötigt wird, ist nicht trivial, und das Default Verhalten der meisten Internet Explorer-Versionen ist, dass das Laden einer neuen Seite ein Klickgeräusch auslöst, was für einige Benutzer verwirrend sein könnte. Bei den meis ten Ajax-Anwendungen ist diese zusätzliche Arbeit die Mühen allerdins wirklich wert.
Steuerelemente über UpdateHistory reparieren Bei ASP.NET AJAX dreht sich alles um aufregende neue JavaScript-Effekte ohne zu viel Progammierarbeit. Sie haben wahrscheinlich also bereits erwartet, dass wir kein Java Script programmieren müssen, um Lesezeichen und die Unterstützung für Vor/Zurück Buttons zu reparieren, sondern dass wir ein externes Modul verwenden werden. Nikhil Kothari von Microsoft (Architekt im ASP.NET AJAX-Team, Vater von Script# und Autor des sehr informativen Weblogs http://nikhilk.netl) hat ein Steuerelement geschrieben, das hier sehr praktisch ist. Es macht nicht alles automatisch, kümmert sich aber um die mühseligsten Aspekte einschließlich des gesamten JavaScript-Codes. Es gibt auch eine Komponente in den Futures, die im folgenden Abschnitt »Eine Reparatur auf Basis der ASP.NET AJAX Futures« behandelt wird. Als dies geschrieben wurde, war die Version 1 . 1 von Kotharis UpdateHistory-Steuerele ment die aktuellste. Der Blog-Eintrag für diese Version befindet sich unter http://www.nikhilk.net/UpdateControlsll .aspx. Wenn eine neue Version herauskommt, wird dieser Blog-Eintrag so aktualisiert, dass er auf das neue Modul verweist. Wenn Sie Kotharis Code herunterladen, halten Sie Ausschau nach der Datei nStuffUpdateControls.dll im bin-Verzeichnis der Site. Kopieren Sie sie in Ihr ASP.NET AJAX-bin-Verzeichnis. Alternativ können Sie sie in den GAC (Global Assembly Cache) kopieren, da dieses Steuerelement sogar signiert ist. Erzeugen Sie dann eine neue .aspx-Datei. Die folgende Direktive lädt die Assembly und definiert außerdem ein Tag-Präfix:
Diese Assembly definiert - unter anderem - das UpdateHistory-Steuerelement. Das ist ein nicht-visuelles Steuerelernent, dass sich um Verlaufseinträge kümmert und Hooks bietet, wenn eine Seite geladen wird - entweder indem sie das erste Mal geladen wird (indem die URL eingegeben oder auf einen Link geklickt wird) oder indem die Vor- oder Zurück Buttons verwendet werden. Das folgende Markup schließt das Steuerelement ein und bereitet außerdem den Event-Handling-Mechanismus für das Laden der Seite vor:
Es gibt einen Haken: Das UpdateHistory-Steuerelement bietet nur serverseitige Hooks. Deswegen sollte ein UpdatePanel-Steuerelement verwendet werden, damit wir einen einfa-
392 I
Kapitel 20: Lesezeichen, Zurück- und Vor-Button reparieren
ehen Mechanismus zum Aufrufen von Servercode haben, ohne dass die vollständige Seite neu geladen werden muss. Als Beispielszenario werden wir das ASP.NET 2.0 Wizard-Steuerelement verwenden. Wenn es in ein UpdatePanel gesteckt wird, funktionieren die Vor- und Zurück-Buttons nicht, zum vorangegangenen Schritt kann also nicht über die Werkzeugleiste des Brow sers zurücknavigiert werden.
Aehtung . . . Fertig . . . Los! An diesem Markup fallen zwei Dinge auf. Erstens ist der UpdateMode des UpdatePanel-Steuer elements auf "Conditional" gesetzt. Später werden wir ein serverseitiges Steuerelement ein setzen wollen, um den Inhalt des Panels zu aktualisieren, wenn wir erkennen, dass der Vor oder Zurück-Button des Browsers angeklickt wurde. Und zweitens wird jedes Mal, wenn ein Benutzer zu einem anderen Schritt des Assistenten (die Eigenschaft OnActiveStepChan ged) navigiert, eine Methode namens stepChanged ( ) ausgeführt. In dieser Methode wird die Nummerdes aktuellen Schritts in das UpdateHistory-Steuereiement geschrieben. Dazu kann die Methode AddEntry() aufgerufen werden. Sie erwartet einen String-Parame teL Andere Datentypen müssen zuvor konvertiert werden. Hier ist der Code:
protected void stepChanged(objeet sender, EventArgs e) { UpdateHistory1.AddEntry( ( (Wizard)sender) .AetiveSteplndex.ToString())j } Die Methode historyNavigateO wird jedes Mal aufgerufen, wenn die Seite oder Inhalt auf ihr geladen wird. Das UpdateHistory-Steuereiement stellt automatisch die damit ver knüpften Verlaufseinträge bereit. Es muss also nur noch dieser Eintrag gelesen und in den entsprechenden Assistentenschritt konvertiert werden. Denken Sie daran, die Informationen zu validieren, um Angreifer abzublocken, wenn Sie versuchen, der URL ungültige Daten anzuhängen:
protected void historyNavigate(objeet sender, HistoryEventArgs e) { int step = 0; if (e. EntryName != null) Steuerelemente über UpdateHistory reparieren I 393
{
int.TryParse(e.EntryName.ToString(), out step); } if (step )= 0 && step < Wizardl.WizardSteps.Count) { Wizardl.ActiveSteplndex = step; } UpdatePanell.Update(); } Beispiel 20-1 enthält den vollständigen Code für dieses Beispiel: Er lädt die UpdateCon tro ls-Assembly, fügt ein UpdateHistory-Steuerelement hinzu und bietet den Code, der erforderlich ist, um Lesezeichen und die Vor- und Zurück-Buttons zum Funktionieren zu bringen. Beispiel 20-1: Lesezeichen und die Vor/Zurück-Buttons reparieren
Bookmarks . aspx < I DOCTYPE htrnl PUBLIC J/W3C1 /DTO XHTML 1.0 Transitional! /EN" ''http://WWW.W3 .orgJTRJxhtmllJDTDJxhtml1transitional. dtd")