informatyka asp net 3 5 tworzenie portali internetowych w nurcie web 2 0 omar al zabir ebook

background image

Wydawnictwo Helion
ul. Koœciuszki 1c
44-100 Gliwice
tel. 032 230 98 63

e-mail: helion@helion.pl

ASP.NET 3.5. Tworzenie
portali internetowych
w nurcie Web 2.0

Autor: Omar Al Zabir
T³umaczenie: Marek Pa³czyñski
ISBN: 978-83-246-1841-5
Tytu³ orygina³u:

Building a Web 2.0

Portal with ASP.NET 3.5

Stron: 320

Poznaj sekrety zaawansowanych technologii budowy

portali internetowych Web 2.0

• Jak zaprojektowaæ witrynê dla platformy ASP.NET i ASP.NET AJAX?
• Jak rozbudowaæ serwis zgodnie z zasadami ergonomii?
• Jak zwiêkszyæ wydajnoœæ serwera?

Portale sieciowe Web 2.0, opieraj¹ce siê na technologii AJAX, umo¿liwiaj¹ u¿ytkownikom
personalizowanie stron, a tak¿e agregowanie danych z ró¿nych Ÿróde³. Wszystko
to sprawia, ¿e s¹ doskona³ymi serwisami korporacyjnymi i nale¿¹ do najefektywniejszych
aplikacji sieciowych. Zastosowanie mechanizmów AJAX pozwala na udostêpnienie
interaktywnego i rozbudowanego interfejsu, dzia³aj¹cego znacznie szybciej i bardziej
wydajnie ni¿ w tradycyjnych serwisach. Natomiast wykorzystanie wid¿etów (komponentów
typu plag-and-play) zapewnia przejrzystoœæ architektury portalu i ³atwoœæ jego rozbudowy,
poniewa¿ s¹ one opracowywane niezale¿nie od warstwy rdzeniowej systemu.

Ksi¹¿ka „ASP.NET 3.5. Tworzenie portali internetowych w nurcie Web 2.0” zawiera opis
najnowszych metod i technologii projektowania oraz budowy portali z wykorzystaniem
platformy ASP.NET i œrodowiska ASP.NET AJAX. W podrêczniku przedstawiono tak¿e
praktyczne rozwi¹zania problemów zwi¹zanych z projektowaniem, wdra¿aniem,
utrzymaniem, a tak¿e skalowaniem i usprawnianiem serwisu. Dziêki tej pozycji poznasz
poszczególne fazy budowy prototypowego portalu, zaawansowane techniki technologii
AJAX oraz sposoby optymalizacji kodu. Nauczysz siê m. in. przygotowywaæ wid¿ety
klienckie za pomoc¹ kodu JavaScript, tworzyæ w³asne mechanizmy obs³ugi wywo³añ,
zwiêkszaæ wydajnoœæ serwera i skalowalnoœæ us³ug sieciowych. Zdobêdziesz zatem ca³¹
potrzebn¹ Ci wiedzê i umiejêtnoœci, które pozwol¹ zbudowaæ stabilny, nowoczesny
i bezpieczny portal internetowy.

• Wprowadzenie do budowy portali internetowych
• Architektura portali i wid¿etów
• Projekt warstwy sieciowej w œrodowisku ASP. NET AJAX
• Projekt warstwy danych i warstwy biznesowej na platformie NET 3.5
• Wid¿ety klienckie
• Optymalizacja pracy œrodowiska ASP.NET AJAX
• Tworzenie asynchronicznych i transakcyjnych us³ug sieciowych
z uwzglêdnieniem buforowania danych
• Skalowalnoœæ us³ug sieciowych
• Zwiêkszenie wydajnoœci serwera i klienckiej czêœci aplikacji
• Zarz¹dzanie witryn¹

Zaprojektuj bardzo wydajn¹ i supernowoczesn¹ witrynê internetow¹

background image

5

Spis tre

ļci

Przedmowa ...............................................................................................................................9

1. Wprowadzenie do portali internetowych i serwisu Dropthings.com ....................... 15

Definicja portalu sieciowego

16

Definicja portalu Web 2.0

18

Korzystanie z portalu

18

Nawigacja w portalu Dropthings

19

Wykorzystanie platformy ASP.NET AJAX

23

Wykorzystanie jözyka C# 3.0 i platformy .NET 3.5

23

Podsumowanie

25

Dodatkowe Ēródäa informacji

25

2. Architektura portalu i wid

żetów ................................................................................27

Wykorzystanie platformy widĔetów

35

Dodawanie widĔetów

41

Wywieranie korzystnego wraĔenia podczas pierwszej wizyty uĔytkownika

43

Przygotowanie strony podczas drugiej wizyty uĔytkownika

46

Zwiökszenie wydajnoĈci kodu ASP.NET AJAX

47

Uwierzytelnianie i autoryzacja

52

Ochrona przed atakami DoS

54

Podsumowanie

56

3. Projekt warstwy sieciowej w

ļrodowisku ASP.NET AJAX .........................................57

Strona startowa portalu sieciowego

57

Budowa wäasnego rozszerzenia „przeciñgnij i upuĈè”

dla wielokolumnowej strefy zrzutu

75

Klasa WidgetContainer

88

Budowanie widĔetów

95

Przeäñczanie stron — symulowanie operacji pobrania strony

105

background image

6

_ Spis treļci

Wykorzystanie obiektu Profile w usäudze sieciowej

107

Implementacja uwierzytelniania i autoryzacji

108

Implementacja mechanizmu wylogowania

110

Podsumowanie

112

Dodatkowe Ēródäa informacji

112

4. Projekt warstwy dost

ýpu do danych i warstwy biznesowej na platformie .NET 3.5 ....113

Podstawy mechanizmu LINQ to SQL

113

Budowanie warstwy dostöpu do danych

z wykorzystaniem mechanizmu LINQ to SQL

116

Podstawy technologii Windows Workflow Foundation

124

Budowa warstwy biznesowej z wykorzystaniem mechanizmu WF

125

Implementacja klasy DashboardFacade

139

Podsumowanie

144

5. Wid

żety klienckie ...................................................................................................... 145

OpóĒnienie äadowania widĔetów serwerowych

146

PoĈrednik w dostöpie do danych

149

Budowa klienckiego widĔetu RSS

153

Budowa klienckiego widĔetu Flickr

157

Podsumowanie

161

6. Optymalizacja pracy

ļrodowiska ASP.NET AJAX ..................................................... 163

Poäñczenie wielu wywoäaþ Ajax w jedno wywoäanie

163

Synchronizacja i kolejkowanie odwoäaþ Ajax

165

Zastosowanie wywoäaþ HTTP GET zamiast HTTP POST

177

Korzystanie z funkcji this

178

Podsumowanie

179

7. Tworzenie asynchronicznych i transakcyjnych us

ĥug sieciowych

z uwzgl

ýdnieniem buforowania danych ...................................................................181

SkalowalnoĈè usäug sieciowych

181

Asynchroniczne metody sieciowe

183

Zmiany w Ĉrodowisku ASP.NET AJAX

umoĔliwiajñce wywoäywanie usäug sieciowych

187

Opracowanie wäasnego mechanizmu obsäugi usäug sieciowych

189

Przygotowanie asynchronicznego poĈrednika,

który bödzie uwzglödniaä buforowanie danych

200

Skalowanie i zabezpieczanie usäug poĈredniczñcych

202

Podsumowanie

207

background image

Spis tre

ļci

_

7

8. Zwi

ýkszanie wydajnoļci i skalowalnoļci serwera ...................................................209

Uzupeänienie kodu o funkcje umoĔliwiajñce identyfikacjö

problemów wydajnoĈciowych

210

Optymalizacja potokowego przetwarzania Ĕñdaþ HTTP

211

Optymalizacja platformy ASP.NET 2.0 (lub 3.5) przed udostöpnieniem serwisu

212

Optymalizacja zapytaþ kierowanych do tabel usäugi ASP.NET Membership

213

Optymalizacja usäugi Profile platformy ASP.NET 2.0 (lub 3.5)

przed udostöpnieniem serwisu

216

Zagadnienia zwiñzane z wykorzystaniem platformy ASP.NET

na serwerach uĔytkowych

231

Przekierowanie ruchu do nowej witryny

233

Podsumowanie

235

9. Zwi

ýkszenie wydajnoļci klienckiej czýļci aplikacji ..................................................237

Buforowanie danych sieciowych

237

Sieci dostarczania treĈci

248

Optymalizacja pracy interpretera JavaScript w przeglñdarce Internet Explorer

252

Zmniejszenie rozmiaru pola danych w wywoäaniach usäug sieciowych

260

ãadowanie interfejsu uĔytkownika na Ĕñdanie

261

Odczyt z wyprzedzeniem w wywoäaniach Ajax

264

Ukrywanie kodu HTML w obszarze <textarea>

264

Podsumowanie

267

10. Rozwi

ézywanie typowych problemów z wdrożeniem i utrzymaniem witryny

oraz zarz

édzaniem nié ..............................................................................................269

Uruchamianie witryny w farmie serwerów

269

TrzynaĈcie katastrof, które mogñ wystñpiè w kaĔdej chwili

276

Wybór odpowiedniej firmy hostingowej

288

Wybór narzödzia do monitorowania pracy witryny

290

Konfiguracja wskaĒników wydajnoĈci

292

Podsumowanie

299

Skorowidz ............................................................................................................................. 301

background image

145

ROZDZIA

Ĥ 5.

Wid

żety klienckie

W rozdziale 3. zostaäy opisane zagadnienia zwiñzane z budowaniem widĔetów serwerowych
— widĔetu czytnika RSS (lub Atom) oraz widĔetu fotograficznego Flickr. Zaletñ stosowania
widĔetów serwerowych jest to, Ĕe moĔna wykorzystywaè komfortowe Ĉrodowisko pracy
(oprogramowania Visual Studio) do ich tworzenia i debugowania, uĔywajñc przy tym swoje-
go ulubionego jözyka programowania (C# lub VB.NET). Jednak widĔety serwerowe opóĒ-
niajñ äadowanie strony i wymagajñ czöstego odsyäania danych. Wszystkie widĔety widoczne
na stronie muszñ zostaè zaäadowane po stronie serwera podczas pierwszego pobierania stro-
ny oraz w czasie jej asynchronicznych uaktualnieþ. JeĈli widĔety pobierajñ dane z zewnötrz-
nych Ēródeä, czas pobierania strony zaleĔy od äñcznego czasu przygotowania kaĔdej z nich.
Ponadto widĔety serwerowe wymagajñ odsyäania danych nawet podczas nieskomplikowa-
nych operacji takich jak stronicowanie lub edytowanie pozycji na liĈcie. Przekazywanie da-
nych jest konieczne, poniewaĔ po stronie serwera jest przechowywany model obiektu, który
z kolei jest powiñzany z informacjami zapisanymi w bazie danych. Po stronie klienta nie sñ
przechowywane Ĕadne informacje, które mogäyby usprawniè niektóre operacje realizowane
w przeglñdarce. Zatem mimo Ĕe widĔety serwerowe znacznie uäatwiajñ opracowywanie ko-
du i zarzñdzanie nim, charakteryzujñ siö niĔszñ wydajnoĈciñ pracy w porównaniu z widĔe-
tami klienckimi.

WidĔety klienckie bazujñ przede wszystkim na technologii JavaScript, dziöki czemu zapew-
niajñ znacznie wyĔszy poziom interaktywnoĈci i funkcjonalnoĈci w operacjach niewymagajñ-
cych odsyäania danych. WidĔety klienckie pobierajñ dane z zewnötrznych Ēródeä bezpoĈred-
nio z poziomu skryptu JavaScript i przechowujñ model obiektu oraz informacje o stanie
obiektu po stronie klienta. Dziöki temu realizujñ zadania stronicowania, edycji czy sortowania
bezpoĈrednio w przeglñdarce bez odsyäania danych do serwera. Co wiöcej, widĔety klienckie
mogñ buforowaè zewnötrzne informacje w pamiöci przeglñdarki, wiöc przygotowywanie
strony podczas kolejnych wizyt uĔytkownika moĔe przebiegaè znacznie szybciej niĔ w przy-
padku widĔetów serwerowych. Dane niezbödne do wyĈwietlenia elementu sñ bowiem prze-
chowywane w przeglñdarce. W tym rozdziale zostanie omówione zagadnienie opóĒnienia
äadowania widĔetów serwerowych w celu przyspieszenia äadowania strony. Rozwiñzanie to
zostanie przedstawione na przykäadzie dwóch klienckich widĔetów — czytnika danych RSS
oraz komponentu wyĈwietlajñcego fotografie serwisu Flickr. Opisana zostanie takĔe procedu-
ra budowy poĈredniczñcej usäugi sieciowej, która pozwoli widĔetom klienckim na pobieranie
danych z zewnötrznych Ēródeä i buforowanie ich w pamiöci przeglñdarki.

background image

146

_

Rozdzia

ĥ 5. Widżety klienckie

Opó

Śnienie ĥadowania widżetów serwerowych

Podczas interpretowania skryptu strony na serwerze konieczne jest wykonanie kodu wszyst-
kich zawartych na niej widĔetów. Powoduje to znaczne opóĒnienie w dostarczaniu treĈci za-
równo podczas pierwszej wizyty, jak i w czasie kolejnych wizyt oraz w przypadku przeäñ-
czania zakäadek. WidĔety pobierajñ dane z zewnötrznych Ēródeä lub serwerowej bazy danych
w kodzie zdarzenia

Page_Load

. Wywoäanie tego zdarzenia w kaĔdym z widĔetów (które

funkcjonujñ w taki sam sposób jak kontrolki sieciowe) okazuje siö czasochäonne. Aby zwiök-
szyè odczuwalnñ szybkoĈè äadowania strony, trzeba dostarczyè do przeglñdarki szkielet wi-
dĔetów wraz z komunikatami informujñcymi o pobieraniu danych, a nastöpnie stopniowo
wypeäniaè poszczególne kontrolki wäaĈciwñ treĈciñ.

Rozwiñzanie to jest wykorzystywane na przykäad w portalu Pageflakes, w którym najpierw
äaduje siö szablon widĔetów, a w obszarze kaĔdej z kontrolek wyĈwietla siö komunikat
o trwajñcym procesie pobierania informacji. KaĔdy z widĔetów wywoäuje usäugö sieciowñ
i pobiera dane niezbödne do wyĈwietlenia swojej zawartoĈci. Mimo Ĕe caäkowity czas äado-
wania strony jest doĈè däugi (kaĔdemu widĔetowi odpowiada co najmniej jedno wywoäanie
usäugi sieciowej), subiektywne odczucie uĔytkownika okazuje siö korzystniejsze, poniewaĔ
moĔe on obserwowaè caäy proces. W rezultacie zaäadowanie kolejno wszystkich widĔetów na
stronö jest postrzegane jako znacznie szybszy proces niĔ w klasycznym mechanizmie gene-
rowania dokumentu.

OpóĒnione äadowanie oznacza, Ĕe widĔety nie pobierajñ danych w kodzie zdarzenia

Page_Load

,

ale w procedurze asynchronicznej aktualizacji wyzwalanej przez komponent stopera. WidĔet
najpierw wyĈwietla komunikat o postöpie äadowania, a nastöpnie wykorzystuje obiekt

Timer

do wyzwolenia asynchronicznej aktualizacji. Z kolei w czasie asynchronicznej aktualizacji
komponent pobiera informacje z zewnötrznych Ēródeä danych i przygotowuje kod wyni-
kowy. Technika ta eliminuje problem wstrzymywania wykonywania procedury

Page_Load

w oczekiwaniu na dostarczenie zewnötrznych danych. Czas äadowania caäej strony nie jest
wówczas uzaleĔniony od szybkoĈci gromadzenia danych z zewnötrznych Ēródeä. Jednym
z najäatwiejszych sposobów implementacji omawianego rozwiñzania jest zastosowanie kon-
trolki

MultiView

, która bödzie zawieraäa widok z komunikatem o postöpie prac oraz widok

obejmujñcy gäówny interfejs uĔytkownika widĔetu. Kontrolka

Timer

moĔe zainicjowaè ode-

säanie danych po pewnym czasie (na przykäad 100 ms), które z kolei spowoduje zmianö
widoku na wäaĈciwy interfejs uĔytkownika oraz wyäñczenie stopera.

Opó

Śnienie ĥadowania widżetu RSS (Atom)

Pierwszy etap prac polega na przeksztaäceniu widĔetu RSS w taki sposób, aby opóĒniä äado-
wanie treĈci, oraz na podzieleniu procedury äadowania danych na dwie fazy. Po modyfikacji
strona bödzie pobierana bardzo szybko. Jednak w miejscu widĔetów wyĈwietli siö komunikat
informujñcy o äadowaniu danych. Poszczególne widĔety bödñ äadowane kolejno jeden po
drugim. Interfejs uĔytkownika widĔetu trzeba wiöc podzieliè na dwa widoki, obsäugiwane
przez kontrolkö

MultiView

. Pierwszy z nich obejmuje jedynie komunikat o postöpie prac.

Natomiast drugi wykorzystuje kontrolkö

DataList

o nazwie

FeedList

. Kod stosownego

skryptu zostaä przedstawiony w listingu 5.1.

background image

Opó

Śnienie ĥadowania widżetów serwerowych

_ 147

Listing 5.1. WidĔet RSS z opóĒnionym äadowaniem podzielony na dwa widoki.

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="RSSWidget.ascx.cs"
Inherits="Widgets_RSSWidget" EnableViewState="false" %>
<asp:Panel ID="SettingsPanel" runat="Server" Visible="False" >
...
</asp:Panel>

<asp:MultiView ID="RSSMultiview" runat="server" ActiveViewIndex="0">

<asp:View runat="server" ID="RSSProgressView">
<asp:image runat="server" ID="image1" ImageAlign="middle"
ImageUrl="~/indicator.gif" />
<asp:Label runat="Server" ID="label1" Text="Loading..." Font-Size="smaller"
ForeColor="DimGray" />
</asp:View>

<asp:View runat="server" ID="RSSFeedView">

<asp:DataList ID="FeedList" runat="Server" EnableViewState="False">
<ItemTemplate>
<asp:HyperLink ID="FeedLink" runat="server" Target="_blank"
CssClass="feed_item_link" NavigateUrl='<%# Eval("link") %>'
ToolTip='<%# Eval("description") %>'>
<%# Eval("title") %>
</asp:HyperLink>
</ItemTemplate>
</asp:DataList>

</asp:View>

</asp:MultiView>

<asp:Timer ID="RSSWidgetTimer" Interval="1" OnTick="LoadRSSView" runat="server" />

Kontrolka

Timer

wywoäuje serwerowñ funkcjö

LoadRSSView

w sposób asynchroniczny.

Funkcja z kolei zmienia bieĔñcy widok na

RSSFeedView

i wyĈwietlane informacje RSS zgod-

nie z kodem zamieszczonym w przykäadzie 5.2. Definicja funkcji znajduje siö w pliku kodu
towarzyszñcym kontrolce sieciowej czytnika RSS.

Listing 5.2. Funkcja LoadRSSView widĔetu RSS wyzwalana przez kontrolkö Timer.

protected void LoadRSSView(object sender, EventArgs e)
{
this.ShowFeeds( );
this.RSSMultiview.ActiveViewIndex = 1;
this.RSSWidgetTimer.Enabled = false;
}

Po wprowadzeniu zmian w czasie pierwszego äadowania funkcja

Page_Load

nie wykonuje

Ĕadnych operacji. Jej zadanie polega na pobieraniu danych RSS jedynie w czasie asynchro-
nicznych aktualizacji. PoniewaĔ procedura obsäugi zdarzenia

Page_Load

koþczy siö bez-

zwäocznie, czas äadowania widĔetu nie zaleĔy od czasu pobrania informacji z zewnötrznych

Ēródeä danych. Kod rozwiñzania zostaä przedstawiony w listingu 5.3.

Listing 5.3. Podczas pierwszego äadowania zdarzenie Page_Load nie powoduje wykonania jakichkolwiek instrukcji.

protected void Page_Load(object sender, EventArgs e)
{
if (!this._Host.IsFirstLoad) this.LoadRSSView(sender, e);
}

background image

148

_

Rozdzia

ĥ 5. Widżety klienckie

Procedura obsäugi zdarzenia

Page_Load

wywoäuje funkcjö

LoadRSSView

jedynie w przypad-

ku aktualizacji. Wówczas kod

LoadRSSView

jest wykonywany bardzo szybko, poniewaĔ dane

zostajñ zapisane w pamiöci podröcznej Ĉrodowiska ASP.NET.

Opó

Śnienie ĥadowania widżetu Flickr

Procedura opóĒnienia äadowania widĔetu Flickr jest analogiczna do procedury opóĒnienia

äadowania widĔetu RSS. Do wyĈwietlenia komunikatu o postöpie prac trzeba zastosowaè
kontrolkö

MultiView

, która jako drugi widok wyĈwietli zaäadowane przez stronö zdjöcia.

W czasie pierwszego pobierania dokumentu kod procedury

Page_Load

nie powinien wyko-

nywaè Ĕadnych czynnoĈci, wiöc nie spowoduje opóĒnienia w dostarczaniu strony. Po prze-
kazaniu komunikatu do przeglñdarki kontrolka

Timer

powinna wywoäaè operacjö asynchro-

nicznej aktualizacji. Wówczas strumieþ plików zdjöciowych zostanie pobrany z serwisu Flickr
i zinterpretowany przez kod interfejsu uĔytkownika.

Problemy wynikaj

éce z opóŚnienia ĥadowania widżetów

Choè czas pobierania strony wydaje siö krótszy, w rzeczywistoĈci caäkowity czas äadowania
danych jest znacznie däuĔszy, poniewaĔ kaĔdy widĔet musi wykonaè co najmniej jednñ asyn-
chronicznñ aktualizacjö. Ponadto technika ta wiñĔe siö ze znacznym obciñĔeniem skryptu
Default.aspx ze wzglödu na koniecznoĈè asynchronicznego aktualizowania danych podczas
pierwszego äadowania. Skrypt Default.aspx nie jest przetwarzany raz, ale n razy przy n wi-
dĔetach o opóĒnionym äadowaniu danych. Asynchroniczne aktualizacje bazujñ na Ĕñdaniach
HTTP POST, wiöc nie ma moĔliwoĈci buforowania informacji pobranych z zewnötrznych

Ēródeä w pamiöci podröcznej przeglñdarki. Nawet jeĈli informacje w danym kanale RSS nie
zmieniñ siö przez tydzieþ, bödñ musiaäy zostaè przesäane z serwera podczas ka

Ĕdej asyn-

chronicznej aktualizacji wykonanej w tym okresie. Dane nie sñ buforowane w przeglñdarce,
wiöc czas kolejnego äadowania widĔetu nie ulega skróceniu.

Na rysunku 5.1 zostaä przedstawiony zapis asynchronicznych aktualizacji z odwoäaniem do
strony Default.aspx wykonanych przez cztery widĔety RSS z zaimplementowanñ funkcjñ opóĒ-
nionego äadowania. We wszystkich przypadkach przesyäane sñ Ĕñdania HTTP POST.

Podczas kolejnych wizyt wykonanie tych samych czterech asynchronicznych aktualizacji
koþczy siö zwróceniem identycznych wyników, poniewaĔ informacje w kanale RSS nie
zmieniajñ siö zbyt czösto. Nie ma jednak moĔliwoĈci zbuforowania odpowiedzi i wyelimi-
nowania w ten sposób niepotrzebnych odwoäaþ. Zgodnie z wczeĈniejszym stwierdzeniem
asynchroniczne aktualizacje, jako Ĕñdania HTTP POST, nie podlegajñ rejestracji w pamiöci
podröcznej.

Aby skróciè czas äadowania widĔetów w czasie kolejnych wizyt, naleĔy pobraè dane z prze-
glñdarki z wykorzystaniem Ĕñdania HTTP GET. Niezbödne jest w tym przypadku wygene-
rowanie takich nagäówków odpowiedzi, które wskaĔñ dane w pamiöci podröcznej przeglñ-
darki. Do pobrania informacji z pierwotnego Ēródäa danych trzeba wykorzystaè skrypt
JavaScript. Musi on równieĔ odpowiednio zinterpretowaè pobrane dane i przygotowaè wäa-
Ĉciwy kod HTML. A poniewaĔ nie moĔna uĔyè serwerowych mechanizmów generowania
kodu HTML, trzeba zaprojektowaè skrypty klienckie w taki sposób, aby wykorzystywaäy dane
z wczeĈniejszych wizyt na stronie.

background image

Po

ļrednik w dostýpie do danych

_ 149

Rysunek 5.1. OdpowiedĒ na Ĕñdanie asynchronicznego uaktualnienia po uwzglödnieniu opóĒnienia
w äadowaniu widĔetu.

Jednak przeglñdarki nie pozwalajñ na miödzydomenowe odwoäania do usäug sieciowych.
Nie moĔna wiöc zastosowaè techniki XML HTTP do bezpoĈredniego pobierania danych z ze-
wnötrznych domen. Niedopuszczalne jest na przykäad zaäadowanie dokumentu XML wprost
spod adresu http://msdn.microsoft.com/rss.xml. MoĔliwe jest natomiast wywoäanie jednej z wäa-
snych usäug sieciowych, która bödzie peäniäa rolö poĈrednika (proxy) w dostöpie do orygi-
nalnego Ēródäa danych. W nastöpnym podrozdziale zostanie przedstawiony sposób przygo-
towania wspomnianego poĈrednika, który bödzie pobieraä informacje spod zewnötrznych
adresów URL i realizowaä zadania zwiñzane z inteligentnym buforowaniem danych.

Po

ļrednik w dostýpie do danych

PoĈrednik w dostöpie do danych jest usäugñ sieciowñ, pracujñcñ na jednym z serwerów ser-
wisu, która moĔe pobieraè informacje spod zewnötrznych adresów URL i przekazywaè je do
przeglñdarki (rysunek 5.2).

Rysunek 5.2. Przeglñdarka wysyäa Ĕñdanie do usäugi poĈrednika, a ta pobiera informacje ze Ēródäa danych.

background image

150

_

Rozdzia

ĥ 5. Widżety klienckie

Usäuga poĈrednika moĔe zbuforowaè dane na serwerze i na pewien czas wyeliminowaè ko-
niecznoĈè ponawiania wywoäaþ pod ten sam adres URL. Na przykäad jeĈli stu uĔytkowni-
ków korzysta z tego samego kanaäu RSS, a informacje w kanale nie zmieniajñ siö przez wiele
dni, usäuga poĈrednika moĔe zbuforowaè dane pochodzñce ze pierwotnego Ēródäa na jeden
dzieþ i obsäugiwaè setki lub tysiñce zapytaþ bezpoĈrednio z wykorzystaniem danych zgro-
madzonych w pamiöci serwera. Opisany mechanizm zostaä zilustrowany na rysunku 5.3.

Rysunek 5.3. Usäuga poĈrednika buforuje dane w pamiöci serwera i uniemoĔliwia wywoäywanie
zewnötrznej usäugi przez wielu uĔytkowników.

Buforowanie danych po stronie serwera znacznie zwiöksza szybkoĈè pobierania informacji,
poniewaĔ ogranicza transmisjö sieciowñ do pojedynczego odwoäania. Serwer nie musi ko-
munikowaè siö z zewnötrznym Ēródäem danych. PoĈrednik moĔe dodatkowo wygenerowaè
nagäówki, które poinformujñ przeglñdarkö o obowiñzku zbuforowania odpowiedzi na okre-

Ĉlony czas. Przed upäywem tego czasu ewentualne odwoäania do poĈrednika bödñ zastöpo-
wane pobraniem danych z pamiöci podröcznej, co jest wyjñtkowo szybkie. Zatem kolejne
odwoäania do serwera proxy w celu pobrania tych samych danych nie bödñ wcale wymagaäy
przesyäania Ĕñdaþ przez sieè, tak jak to zostaäo pokazane na rysunku 5.4.

Rysunek 5.4. JeĈli odpowiedĒ jest zbuforowana w pamiöci przeglñdarki, Ĕñdanie nie zostaje dostarczone
do poĈrednika, przez co nie powoduje wygenerowania jakiegokolwiek ruchu sieciowego.

Oznacza to, Ĕe jeĈli usäuga poĈrednika pobierze dane RSS i wymusi zbuforowanie ich w prze-
glñdarce na godzinö, uĔytkownik bödzie mógä przejĈè do innego serwisu, a po powrocie widĔet
RSS natychmiast wyĈwietli swojñ treĈè bez odwoäywania siö do serwera. JeĔeli wiöc dana

background image

Po

ļrednik w dostýpie do danych

_ 151

strona byäaby zäoĔona z samych widĔetów RSS, caäa jej treĈè zostaäaby zaäadowana po jed-
nym odwoäaniu do skryptu Default.aspx. Wszystkie pozostaäe informacje byäyby zarejestro-
wane w pamiöci podröcznej przeglñdarki. Zasada wykorzystania mechanizmu buforowania
danych po stronie klienta do zwiökszenia szybkoĈci pobierania danych RSS zostaäa opisana
w rozdziale 9.

Us

ĥuga sieciowa poļrednika w dostýpie do danych

Usäuga poĈrednika w dostöpie do danych zostaäa zdefiniowana w pliku Proxy.asmx i obej-
muje trzy metody:

GetString(url, cacheDuration)

Metoda ta zwraca dane spod okreĈlonego adresu URL w formie ciñgu tekstowego i bufo-
ruje je po stronie przeglñdarki na okreĈlony czas (

cacheDuration

).

GetXml(url, cacheDuration)

Metoda ta zwraca dokument XML pobrany spod okreĈlonego adresu URL i buforuje go
po stronie przeglñdarki na okreĈlony czas (

cacheDuration

).

GetRss(url, count, cacheDuration)

Metoda ta pobiera spod okreĈlonego adresu URL dane kanaäu RSS przeksztaäcone w pro-
jekcjö LINQ (opisanñ w rozdziale 3.). Informacje sñ przechowywane po stronie serwera
przez 15 minut, a po stronie klienta zgodnie z wartoĈciñ

cacheDuration

.

Dziaäanie metod

GetString

i

GetXml

nie jest szczególnie skomplikowane. Sprowadza siö do

uĔycia obiektu

WebClient

w celu pozyskania danych spod podanego adresu URL i zbuforo-

wania odpowiedzi na okreĈlony czas w pamiöci podröcznej. Kod obydwu metod zostaä przed-
stawiony w listingu 5.4.

Listing 5.4. Metody GetString i GetXml usäugi sieciowej poĈrednika.

[WebMethod]
[ScriptMethod(UseHttpGet=true)]
public string GetString(string url, int cacheDuration)
{
using( WebClient client = new WebClient( ) )
{
string response = client.DownloadString(url);
this.CacheResponse(cacheDuration);
return response;
}
}

[WebMethod]
[ScriptMethod(UseHttpGet = true, ResponseFormat=ResponseFormat.Xml)]
public string GetXml(string url, int cacheDuration)
{
return GetString(url, cacheDuration);
}

RóĔnica miödzy metodami

GetString

i

GetXml

sprowadza siö do tego, Ĕe metoda

GetString

zwraca ciñg treĈci zgodnie z formatem JSON, natomiast metoda

GetXml

zwraca ciñg tekstowy

dokumentu XML. Atrybut

ResponseFormat

metody

GetXml

stanowi informacjö dla Ĉrodowi-

ska ASP.NET AJAX o obowiñzku wygenerowania dokumentu XML w formie zwykäego tekstu
zamiast przeksztaäcania go w format JSON.

background image

152

_

Rozdzia

ĥ 5. Widżety klienckie

Metoda

GetRss

jest jednak nieco bardziej skomplikowana. Jej zadanie polega na pobraniu

danych kanaäu RSS i przechowaniu ich przez 15 minut w pamiöci podröcznej platformy
ASP.NET. Dziöki temu kolejne odwoäania do tego samego serwera sñ realizowane z wyko-
rzystaniem pamiöci podröcznej Ĉrodowiska ASP.NET. Metoda

GetRss

przygotowuje dodat-

kowo specjalny nagäówek odpowiedzi, który zapewnia zbuforowanie danych po stronie
przeglñdarki na okreĈlony czas. WidĔet przetwarzajñcy informacje RSS moĔe wiöc kontrolo-
waè czas przechowywania odpowiedzi w przeglñdarce.

W listingu 5.5 zostaä zawarty ten sam kod äadowania i interpretacji danych RSS, który zostaä
zaprezentowany w rozdziale 3. w czöĈci dotyczñcej widĔetu RSS.

Listing 5.5. Metoda GetRss w usäudze sieciowej poĈrednika.

[WebMethod]
[ScriptMethod(UseHttpGet = true)]
public object GetRss(string url, int count, int cacheDuration)
{
var feed = Context.Cache[url] as XElement;
if( feed == null )
{
if( Context.Cache[url] == string.Empty ) return null;
try
{
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;

request.Timeout = 15000;
using( WebResponse response = request.GetResponse( ) )
{
using( XmlTextReader reader = new XmlTextReader( response.
GetResponseStream( ) ) )
{
feed = XElement.Load(reader);
}
}

if( feed == null ) return null;
Context.Cache.Insert(url, feed, null, DateTime.MaxValue, TimeSpan.
FromMinutes(15));
}
catch
{
Context.Cache[url] = string.Empty;
return null;
}
}

XNamespace ns = "http://www.w3.org/2005/Atom";

// Sprawdzenie, jakie dane s

ą przetwarzane: RSS czy Atom.

try
{
// RSS.
if( feed.Element("channel" ) != null )
return (from item in feed.Element("channel").Elements("item")
select new
{
title = item.Element("title").Value,
link = item.Element("link").Value,
description = item.Element("description").Value
}).Take(count);

background image

Budowa klienckiego wid

żetu RSS

_ 153

// Atom.
else if( feed.Element(ns + "entry") != null )
return (from item in feed.Elements(ns + "entry")
select new
{
title = item.Element(ns + "title").Value,
link = item.Element(ns + "link").
Attribute("href").Value,
description = item.Element(ns + "content").Value
}).Take(count);

// B

áĊdny format.

else
return null;
}
finally
{
this.CacheResponse(cacheDuration);
}
}

Trudno

ļci w projektowaniu usĥugi sieciowej poļrednika

W aplikacjach bazujñcych na widĔetach klienckich usäuga sieciowa poĈrednika jest najczöĈciej
wykorzystywanñ usäugñ sieciowñ witryny. Za kaĔdym razem, kiedy skrypt JavaScript musi
pobraè dane z zewnötrznej domeny, musi teĔ wywoäaè jednñ z metod usäugi. W zwiñzku
z tym podczas projektowania usäugi sieciowej poĈrednika trzeba wziñè pod uwagö wiele za-
gadnieþ zwiñzanych ze skalowalnoĈciñ rozwiñzania. Poäñczenie generowane przez tysiñce
widĔetów, które z kolei wymuszajñ ustanowienie tysiöcy poäñczeþ z serwerami spoza dome-
ny, wprowadza istotne obciñĔenie procesów ASP.NET. Czas odpowiedzi zdalnych serwerów
jest nieprzewidywalny i zmienny. Mocno obciñĔony serwis zewnötrzny moĔe dostarczyè od-
powiedĒ po 20 lub nawet 30 sekundach, co oznacza, Ĕe odwoäanie do usäugi poĈrednika zo-
stanie na ten czas zawieszone. JeĈli taki problem siö powtórzy dla 100 Ĕñdaþ przychodzñcych,
wszystkie dostöpne wñtki robocze Ĉrodowiska ASP.NET zostanñ wykorzystane. Aplikacja
sieciowa nie bödzie mogäa obsäugiwaè Ĕadnych Ĕñdaþ, dopóki Ĕñdania przesäane do zdalnych
usäug nie zostanñ zrealizowane lub przerwane (poniewaĔ dopuszczalny czas realizacji upäy-
nie) i nie zwolniñ wñtku roboczego ASP.NET. UĔytkownicy bödñ mieli wraĔenie powolnego
dziaäania serwisu lub nawet zaobserwujñ brak reakcji na Ĕñdania. Zagadnienia zwiñzane ze
skalowalnoĈciñ aplikacji sieciowych, które w duĔej mierze zaleĔñ od dziaäania usäug sie-
ciowych, oraz z pobieraniem informacji z zewnötrznych Ēródeä danych zostaäy opisane
w rozdziale 6.

Po zaimplementowaniu opisanych rozwiñzaþ dysponujemy wszystkimi metodami, które sñ
potrzebne do pobierania informacji z zewnötrznych Ēródeä danych bezpoĈrednio do przeglñ-
darki z wykorzystaniem serwera proxy.

Budowa klienckiego wid

żetu RSS

Utwórzmy klienckñ wersjö widĔetu RSS. Informacje z kanaäu RSS moĔna buforowaè po stro-
nie klienta, poniewaĔ nie zmieniajñ siö szczególnie czösto. Nic nie stoi na przeszkodzie, aby
byäy przechowywane w pamiöci podröcznej na przykäad przez godzinö. Pamiötajmy, Ĕe po-
pularne serwisy RSS majñ wielu odbiorców, a buforowanie informacji po stronie serwera

background image

154

_

Rozdzia

ĥ 5. Widżety klienckie

i dostarczanie ich do setek lub tysiöcy uĔytkowników eliminuje koniecznoĈè wielokrotnego
pobierania tych samych danych bezpoĈrednio ze Ēródäa informacji.

Oto wykaz kilku najwaĔniejszych róĔnic miödzy klienckimi i serwerowymi widĔetami RSS:

x

WidĔet kliencki nie pozyskuje danych RSS za pomocñ kodu serwerowego, wiöc nie
obejmuje kodu LINQ to XML, który pobieraäby odpowiedni dokument XML. Kod LINQ
to XML jest zawarty w usäudze poĈrednika.

x

WidĔet kliencki nie jest wyposaĔony w kontrolkö

MultiView

. Komunikat o postöpie prac

jest wyĈwietlany przez skrypt JavaScript.

x

WidĔet kliencki nie zawiera kontrolki

DataList

, poniewaĔ odpowiedni kod HTML zwiñ-

zany z kanaäami RSS jest generowany przez skrypt JavaScript.

x

Zaäadowanie danych RSS do przeglñdarki naleĔy do zadaþ klasy JavaScript o nazwie

FastRssWidget

, zapisanej w pliku FastRssWidget.js. Klasa ta odpowiada za wywoäanie

usäugi sieciowej poĈrednika i zinterpretowanie pozyskanych danych.

x

W rozwiñzaniu bazujñcym na widĔetach klienckich obiekt klasy

FastRssWidget

jest po-

woäywany przez kontrolkö serwerowñ. Ta sama kontrolka przekazuje odpowiedni skrypt
startowy z adresami URL kanaäów i äaduje caäy kod do przeglñdarki klienckiej.

Analizujñc listing 5.6, moĔna zauwaĔyè, Ĕe poza obszarem ustawieþ i pustym panelem widĔet
nie zawiera Ĕadnych elementów interfejsu uĔytkownika.

Listing 5.6. W nowej wersji rozwiñzania skrypt FastRssWidget.ascx nie zawiera prawie Ĕadnych elementów
interfejsu uĔytkownika.

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="FastRssWidget.ascx.cs"
Inherits="Widgets_FastRssWidget" EnableViewState="false" %>
<asp:Panel ID="SettingsPanel" runat="Server" Visible="False" >
...
</asp:Panel>

<asp:Panel ID="RssContainer" runat="server"></asp:Panel>

W serwerowym kodzie widĔetu zdarzenie

Page_Load

rejestruje znacznik wäñczenia skryptu

FastRssWidget.js, zgodnie z przykäadem zamieszczonym w listingu 5.7.

Listing 5.7. Zdarzenie Page_Load kontrolki FastRssWidget dodaje znacznik skryptu odpowiedzialny
za zaäadowanie pliku FastRssWidget.js, a nastöpnie inicjalizuje klasö, wyĈwietlajñcñ dane po stronie klienta.

protected void Page_Load(object sender, EventArgs e)
{
if (this._Host.IsFirstLoad)
{
ScriptManager.RegisterClientScriptInclude(this,
typeof(Widgets_FastRssWidget),
"FastRssWidget",
this.ResolveClientUrl(
this.AppRelativeTemplateSourceDirectory
+ "FastRssWidget.js"));

ScriptManager.RegisterStartupScript(this,
typeof(Widgets_FastRssWidget),
"LoadRSS",
string.Format("
var rssLoader{0} =
new FastRssWidget( '{1}', '{2}', {3} );

background image

Budowa klienckiego wid

żetu RSS

_ 155

rssLoader{0}.load( );",
this.UniqueID,
this.Url,
this.RssContainer.ClientID,
this.Count),
true);
}
}

Nastöpnie kod zdarzenia wprowadza instrukcjö JavaScript, która powoäuje obiekt klasy
i przekazuje do niej adres URL, identyfikator zewnötrznego panelu klienckiego oraz liczbö
pozycji kanaäu, które naleĔy wyĈwietliè. Operacja ta jest realizowana tylko raz, podczas pierw-
szego äadowania widĔetu. Klasa kliencka wykorzystuje te trzy parametry, odwoäujñc siö do
usäugi poĈrednika. W odpowiedzi na Ĕñdanie otrzymuje dane RSS, które przeksztaäca w od-
syäacze wyĈwietlane w zewnötrznym panelu. Identyfikator panelu jest przekazywany do kla-
sy klienckiej z serwera. SäuĔy on do wyznaczenia elementu

DIV

,

który powinien zostaè wyko-

rzystany do wyĈwietlenia odsyäaczy.

Jednak podczas odsyäania danych po stronie klienta trzeba ponownie wygenerowaè kod tre-
Ĉci kontrolki. A to dlatego, Ĕe operacja asynchronicznej aktualizacji uwzglödnia odesäanie do
przeglñdarki pustego panelu kontenera bez odsyäaczy wygenerowanych wczeĈniej przez
skrypt JavaScript. W praktyce w czasie asynchronicznych uaktualnieþ usuwane sñ wszystkie
elementy interfejsu uĔytkownika, które zostaäy utworzone w wyniku dziaäania kodu klienc-
kiego. Odpowiedni skrypt JavaScript musi je wiöc odtworzyè po kaĔdorazowym odesäaniu
danych. Zadanie to jest realizowane przez procedurö obsäugi zdarzenia

OnPreRender

. Przesyäa

ona do jednostki klienckiej blok skryptu, który przywraca poczñtkowñ wartoĈè adresu URL
oraz wartoĈè parametru

Count

, a nastöpnie wywoäuje funkcjö

load

wczeĈniej utworzonego

obiektu klasy

FastRssWidget

. Caäa operacja jest zbliĔona do procedury pierwszego äadowania

kodu, podczas której tworzony jest obiekt klasy z odpowiednimi parametrami i wywoäywana
jest funkcja

load

. Jedyna róĔnica polega na tym, Ĕe za drugim razem nie jest tworzony nowy

obiekt klasy — realizacja kodu bazuje na zaäoĔeniu, Ĕe obiekt juĔ istnieje. Rozwiñzanie to zo-
staäo przedstawione w listingu 5.8.

Listing 5.8. W czasie zdarzenia OnPreRender do klienta jest wysyäany blok skryptu, który odĈwieĔa interfejs
uĔytkownika.

protected override void OnPreRender(EventArgs e)
{

base.OnPreRender(e);

if (!this._Host.IsFirstLoad)
ScriptManager.RegisterStartupScript(this,
typeof(Widgets_FastRssWidget),
"LoadRSS",
string.Format("
rssLoader{0}.url = '{1}';
rssLoader{0}.count = {2};
rssLoader{0}.load( );",
this.UniqueID,
this.Url,
this.Count),
true);
}

background image

156

_

Rozdzia

ĥ 5. Widżety klienckie

To wszystkie zmiany wprowadzane po stronie serwera. Kod klasy klienckiej jest nieco bar-
dziej skomplikowany. Trzeba bowiem przenieĈè znacznñ czöĈè skryptu serwerowego do kodu
klienckiego. TreĈè klasy jest zapisana w pliku FeedRssWidget.js.

Konstruktor klasy oraz funkcja

load

zostaäy przestawione w listingu 5.9.

Listing 5.9. Kliencka klasa FeedRssWidget.

var FastRssWidget = function(url, container, count)
{
this.url = url;
this.container = container;
this.count = count;
}

FastRssWidget.prototype = {

load : function( )
{
var div = $get( this.container );
div.innerHTML = "Loading...";
Proxy.GetRss ( this.url, this.count, 10, Function.createDelegate( this, this.
onContentLoad ) );
},

Parametry przekazywane do konstruktora to adres URL, identyfikator kontenera oraz liczba
odsyäaczy prezentowanych w obszarze treĈci. Pobranie informacji RSS naleĔy do zdaþ meto-
dy

load

, która z kolei wywoäuje funkcjö

Proxy.GetRss

, przekazujñc do niej ciñg URL, infor-

macjö o liczbie odsyäaczy oraz czas przechowywania danych w pamiöci podröcznej (wyraĔo-
ny w minutach). OdpowiedĒ jest buforowana na 10 minut, wiöc powtórne pobranie strony
lub ponowne przejĈcie do strony po wizycie w innym serwisie w ciñgu 10 minut spowoduje
dostarczenie odpowiedzi bezpoĈrednio z pamiöci podröcznej przeglñdarki bez ustanawiania
poäñczenia z usäugñ sieciowñ poĈrednika. Funkcja obsäugi odpowiedzi zostaäa przedstawiona
w listingu 5.10.

Listing 5.10. Metoda Proxy.GetRss wywoäuje funkcjö onContentLoad jako funkcjö zwrotnñ,
generujñcñ odsyäacze do komunikatów kanaäu.

onContentLoad : function( rss )
{
var div = $get( this.container );
div.innerHTML = "";

for( var i = 0; i < rss.length; i ++ )
{
var item = rss[i];

var a = document.createElement("A");
a.href = item.link;
a.innerHTML = item.title;
a.title = item.description;
a.className = "feed_item_link";
a.target = "_blank";
div.appendChild(a);
}
}

background image

Budowa klienckiego wid

żetu Flickr

_ 157

Funkcja

onContentLoad

tworzy odsyäacze do poszczególnych komunikatów RSS w kodzie

klienckim. Przygotowany w ten sposób widĔet kliencki ma kilka zalet w porównaniu z wi-
dĔetem serwerowym. Oto one:

x

Nie sñ pobierane Ĕadne dane mechanizmu

ViewState

, poniewaĔ kontrolka sieciowa nie

obejmuje prawie Ĕadnych elementów interfejsu uĔytkownika. IloĈè danych przekazywa-
nych podczas pierwszego äadowania i w czasie asynchronicznych uaktualnieþ jest nie-
wielka.

x

TreĈè kontrolki jest buforowana w pamiöci przeglñdarki, co eliminuje koniecznoĈè wy-
miany danych przez sieè.

x

TreĈè kontrolki jest dostarczana za pomocñ usäugi poĈrednika, a nie w wyniku asyn-
chronicznej aktualizacji. Rozwiñzanie to pozwala na wykorzystanie zalet buforowania
serwerowego.

Budowa klienckiego wid

żetu Flickr

Budowa klienckiego widĔetu Flickr przebiega wedäug tych samych zasad, które obowiñzujñ
podczas przygotowywania widĔetu RSS. Kod serwerowy nie dostarcza gotowego dokumentu
HTML. Klasa kliencka pozyskuje stosowny kod za poĈrednictwem metody

Proxy.GetXml

.

Pobiera caäy dokument XML do jednostki klienckiej, co pozwala na uzupeänienie go w prze-
glñdarce o funkcje stronicowania äadowanych zdjöè i nie wymaga asynchronicznych aktuali-
zacji lub wywoäaþ poĈrednich. UĔytkownik moĔe przeglñdaè zdjöcia po bardzo krótkim cza-
sie oczekiwania, a zwrócony dokument XML zostaje przechowany w pamiöci podröcznej
przeglñdarki przez 10 minut. W przypadku ewentualnych kolejnych wizyt (w ciñgu 10 mi-
nut) dokument XML zostanie dostarczony z bufora przeglñdarki, wiöc widĔet Flickr zaäaduje
siö natychmiast i bez koniecznoĈci asynchronicznego aktualizowania treĈci lub odwoäaþ do
usäugi poĈrednika.

Kliencka klasa

FastFlickrWidget

ma ten sam format, jaki zostaä opisany w przypadku klasy

FastRssWidget

. TreĈè klasy znajduje siö w pliku Widgets\FastFlickrWidget.js. Jest równieĔ

przedstawiona w listingu 5.11.

Listing 5.11. Konstruktor i funkcja load klasy FastFlickrWidget.

var FastFlickrWidget = function(url, container, previousId, nextId)
{
this.url = url;
this.container = container;
this.pageIndex = 0;
this.previousId = previousId;
this.nextId = nextId;
this.xml = null;
}

FastFlickrWidget.FLICKR_SERVER_URL="http://static.flickr.com/";
FastFlickrWidget.FLICKR_PHOTO_URL="http://www.flickr.com/photos/";

FastFlickrWidget.prototype = {
load : function( )
{
this.pageIndex = 0;

background image

158

_

Rozdzia

ĥ 5. Widżety klienckie

var div = $get( this.container );
div.innerHTML = "Loading...";

Proxy.GetXml( this.url, 10, Function.createDelegate(this,
this.onContentLoad));
},
onContentLoad : function( xml )
{
this.xml = xml;
this.showPhotos( );
},

Konstruktor klasy pobiera cztery parametry: adres URL kanaäu Flickr, identyfikator elementu

DIV

bödñcego kontenerem dla treĈci oraz identyfikatory odsyäaczy do wczeĈniejszej i nastöp-

nej strony. Przekazanie odsyäaczy jest niezbödne, poniewaĔ kod klasy zmienia sposób ich
prezentacji w zaleĔnoĈci od indeksu przeglñdanej strony.

Funkcja

showPhotos

(przedstawiona w listingu 5.12) wykonuje wszystkie operacje niezbödne

do utworzenia tabeli (o wymiarach 3x3 pola) oraz wyĈwietlenia odsyäaczy i zdjöè.

Listing 5.12. Funkcja showPhotos z pliku FastFlickrWidget.js.

showPhotos : function( )
{
var div = $get( this.container );
div.innerHTML = "";

if( null == this.xml )
return (div.innerHTML = "Error occured while loading Flickr feed");

var photos = this.xml.documentElement.getElementsByTagName("photo");

var row = 0, col = 0, count = 0;

var table = document.createElement("table");
table.align = "center";
var tableBody = document.createElement("TBODY");
table.appendChild( tableBody );
var tr;

for( var i = 0; i < 9; i ++ )
{
var photo = photos[i + (this.pageIndex * 9)];

if( photo == null )
{
Utility.nodisplay( this.nextId );
break;
}

if( col == 0 )
{
tr = document.createElement("TR");
tableBody.appendChild(tr);
}

var td = document.createElement("TD");

var img = document.createElement("IMG");
img.src = this.getPhotoUrl(photo, true);
img.style.width = img.style.height = "75px";
img.style.border = "none";

background image

Czytaj dalej...

Budowa klienckiego wid

żetu Flickr

_ 159

var a = document.createElement("A");
a.href = this.getPhotoPageUrl(photo);
a.target = "_blank";
a.title = this.getPhotoTitle(photo);

a.appendChild(img);
td.appendChild(a);
tr.appendChild(td);

if( ++ col == 3 ) { col = 0; row ++ }
}

div.appendChild(table);

if( this.pageIndex == 0 ) Utility.nodisplay(this.previousId);
},
previous : function( )
{
this.pageIndex --;
this.showPhotos( );
Utility.display( this.nextId, true );
if( this.pageIndex == 0 )
Utility.nodisplay( this.previousId );
},

next : function( )
{
this.pageIndex ++;
this.showPhotos( );
Utility.display( this.previousId, true );
}

PowyĔszy kod powstaä niemal wprost z przeksztaäcenia kodu C# serwerowego widĔetu
Flickr w odpowiadajñcy mu skrypt JavaScript. MoĔna w nim zauwaĔyè odwoäania do klasy

Utility

, która jest niestandardowñ klasñ, obejmujñca kilka uĔytecznych funkcji, odpowie-

dzialnych miödzy innymi za wyĈwietlanie i ukrywanie elementów interfejsu uĔytkownika
oraz przetwarzanie elementów modelu DOM w sposób niezaleĔny od rodzaju przeglñdarki.
Kod klasy

Utility

jest zawarty w pliku MyFramework.js zapisanym w gäównym katalogu projektu.

Kontrolka serwerowa obejmuje panel ustawieþ i podstawowe elementy interfejsu uĔytkow-
nika — pusty kontener oraz odsyäacze do poprzedniej i nastöpnej strony. Deklaracja kontrolki
zostaäa przedstawiona w listingu 5.13.

Listing 5.13. Plik FastFlickrWidget.ascx.

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="FastFlickrWidget.ascx.cs"
Inherits="Widgets_FastFlickrWidget" EnableViewState="false" %>
<asp:Panel ID="settingsPanel" runat="server" Visible="False">
...
</asp:Panel>

<asp:Panel ID="FlickrPhotoPanel" runat="server">

</asp:Panel>

<div style="text-align: center; width:100%; white-space:nowrap">
<asp:LinkButton ID="ShowPrevious" runat="server" >< Prev</asp:LinkButton>
&nbsp;
<asp:LinkButton ID="ShowNext" runat="server" >Next ></asp:LinkButton></center>
</div>


Wyszukiwarka

Podobne podstrony:
ASP NET 3 5 Tworzenie portali internetowych w nurcie Web 2 0 aspn35
ASP NET 2 0 Tworzenie witryn internetowych z wykorzystaniem C i Visual Basica aspntw
ASP NET 2 0 Tworzenie witryn internetowych z wykorzystaniem C i Visual Basica aspntw
informatyka asp net ajax programowanie w nurcie web 2 0 christian wenz ebook
Podstawy ASP NET 2 0 – tworzenie stron WWW oraz aplikacji Web
R15-T, Informatyka, ASP.NET
R12-T, Informatyka, ASP.NET
R13-T, Informatyka, ASP.NET
R20-T, Informatyka, ASP.NET

więcej podobnych podstron