Do tej pory przyjrzeliśmy się przykładom kodów wykorzystujących obiekt Request w celu uzyskania danych od naszego gościa oraz informacji o nim samym. Korzystaliśmy z obiektu Response, aby wysyłać dane z powrotem do przeglądarki odwiedzającego. Tego samego obiektu Response używaliśmy również w celu wysyłania informacji do innej strony przy pomocy łącza lub metody Redirect wraz z zapytaniem. Wiemy też, jak komunikować się z serwerem. Lecz do tej pory nie poznaliśmy metod dzielenia informacji pomiędzy stronami tak, aby mogły być wykorzystywane przez wszystkich gości lub jedynie niektórych z nich. Ten rozdział koncentruje się na tym temacie: na aplikacjach ASP.
Jeśli na co dzień programujesz w jakimś innym języku lub tylko słyszałeś, jak rozmawiają ze sobą programiści, możesz być już zaznajomiony ze słowem stan (state), odnoszący się do trwałości informacji w obrębie danej aplikacji. W aplikacjach bezstanowych wszystkie dane są tracone podczas przechodzenia od jednej procedury do drugiej. Tak więc każde wywołanie lub (jak to jest w wypadku stron ASP) każda strona musi dysponować własnym zestawem danych. Aplikacja posiadająca stan zachowuje informacje podczas kolejnych wywołań, do których to informacji dostęp uzyskać może wiele procedur aplikacji lub ta sama procedura, ale wielokrotnie.
Jeśli kiedykolwiek programowałeś w Visual Basicu, zapewne znasz już zmienne Public i Global. Zmienne te mogą być widoczne w obrębie całej aplikacji od jej uruchomienia aż do zamknięcia. W Visual Basicu deklarujesz tego typu zmienną w następujący sposób:
Public EmpName as String
Możesz ustalić jej wartość w dowolnej procedurze:
EmpName = "Nancy"
Kiedy procedura ustalająca wartość zmiennej kończy swe działanie, wartość tą w dalszym ciągu stanowi tekst Nancy, tak więc inne procedury lub ta sama procedura może odwoływać się do ust 232s189c awionej ostatnio wartości tej zmiennej. Taka aplikacja posiada swój stan. Widzieliśmy, że w większości kodów prezentowanych do tej pory nie mieliśmy możliwości takich odwołań. Zmienne tworzyliśmy używając w kodzie strony instrukcji Dim
Dim EmpName
Jednak gdy tylko przetwarzanie strony zostaje ukończone, dana ulokowana w zmiennej EmpName jest tracona. Żadna inna strona nie może odnosić się do tej zmiennej, jeśli została ona zdeklarowana w ten sposób. Stworzyliśmy strony, które są bezstanowe.
W tym rozdziale zwrócimy uwagę na tworzenie aplikacji ASP pozwalających na utrzymywanie stanu. Aplikacja ASP dostarcza mechanizmów zapamiętywania informacji o stanie we wszystkich stronach. Informacja ta może być zapamiętana na dwóch poziomach: poziomie aplikacji i poziomie sesji.
Poziom aplikacji odnosi się do wszystkich stron aplikacji ASP oraz wszystkich gości twojej aplikacji, możesz więc stworzyć zmienną w jednym położeniu, do której to zmiennej wszystkie strony aplikacji i wszyscy odwiedzający mogliby się odwoływać. Informacja o aplikacji jest wywoływana i tworzona poprzez obiekt Application
Informacje o stanie możesz również zapamiętać na poziomie sesji, który odnosi się do jednego tylko gościa witryny. W tym przypadku informacja o stanie znajduje się na niższym poziomie od poziomu aplikacji. Informacja jest dostępna dla określonego gościa na wszystkich stronach. Oznacza to, że możesz stworzyć informację o stanie aplikacji, która jest widoczna poprzez kod dla jednego tylko odwiedzającego. Ten poziom jest kodowany przez obiekt Session
Jak się dowiesz bardziej szczegółowo z niniejszego rozdziału, obiekty Session i Application mogą obsługiwać wystąpienie określonych zdarzeń, tak więc możesz dysponować kodem uruchamianym podczas rozpoczęcia działania aplikacji lub podczas wchodzenia odwiedzającego na witrynę. Te funkcje naprawdę podnoszą możliwości twoich witryn WWW.
Aplikacja ASP jest serią połączonych ze sobą stron ASP oraz pliku o nazwie global.asa. Wszystkie pliki aplikacji ASP muszą znajdować się w tej samej strukturze katalogu głównego, w którym aplikacja jest zdefiniowana lub w jego podkatalogach.
Spójrz na strukturę katalogu pokazaną na rysunku 8.1.
Rysunek 8.1. Przykładowa struktura katalogu
Aplikacja ASP składa się z wszystkich plików znajdujących się w katalogu głównym lub w dowolnym jego podkatalogu, chyba że podkatalog ten należy do innej aplikacji ASP. Patrząc na nasz przykład widzimy, że najwyższy poziom nie jest zdefiniowany jako aplikacja ASP. Następnie mamy podkatalog o nazwie HR, który zdefiniowany jest jako aplikacja ASP, tak więc strony ASP w tym katalogu są częścią jednej aplikacji HR.
Powiedzieliśmy również, że podkatalogi są częścią aplikacji, o ile nie stanowią swojej własnej aplikacji ASP. W katalogu HR znajduje się katalog o nazwie NewEmps. Nie jest on aplikacją ASP, tak więc każda strona w nim się znajdująca należy do aplikacji HR. Jeśli katalog NewEmps zawiera w sobie jakieś podkatalogi, one również będą składnikami aplikacji ASP, chyba że zostały zdefiniowane jako własna, odrębna aplikacja ASP.
Drugim podkatalogiem HR jest Train. Ten katalog sam w sobie jest aplikacją ASP, więc strony ASP znajdujące się w nim nie należą do aplikacji HR. W katalogu Train znajduje się podkatalog C1. Ponieważ nie jest on katalogiem ASP, należy do aplikacji Train, znajduje się bowiem na niższym poziomie w stosunku do niej.
W katalogu głównym znajduje się ponadto katalog o nazwie IS, który zdefiniowany jest jako aplikacja ASP, tak więc wszystkie strony ASP w tym katalogu będą należały do aplikacji IS, a nie HR czy jakiejkolwiek innej.
Ostatnim podkatalogiem katalogu głównego jest Sales. Nie jest on aplikacją ASP, więc strony znajdujące się w nim są bezstanowe. Nie należą one do żadnej aplikacji ASP, ponieważ ani katalog, w którym się znajdują, ani żaden katalog nadrzędny nie jest zdefiniowany jako aplikacja ASP.
Tworząc aplikację ASP musisz orientować się, w którym miejscu umieszczasz poszczególne strony, aby ich względne położenie gwarantowało możliwość dzielenia między sobą informacji o stanie. Normalnie dokonasz tego tworząc katalog podrzędny w stosunku do katalogu głównego twojej witryny WWW. Następnie umieszczasz w obrębie tego katalogu wszystkie pliki będące częścią aplikacji.
Teraz jesteś już gotowy do oznaczenia katalogu jako aplikacji ASP. Możesz to zrobić klikając katalog prawym przyciskiem myszy w oknie Konsoli zarządzania Microsoftu serwera IIS, a następnie wybierając Właściwości (Properties), jak to zaprezentowano na rysunku 8.2.
Rysunek 8.2. Przeglądanie Właściwości w celu stworzenia aplikacji ASP
Po wybraniu Właściwości (Properties powinieneś ujrzeć dialog pokazany na rysunku 8.3. Kiedy już znajdziesz się we właściwościach katalogu, powinieneś znaleźć się w zakładce Katalog Directory ; jeśli tak nie jest, zmień zakładkę. Następnie naciśnij przycisk Utwórz Create w sekcji Ustawienia aplikacji Application Settings i wprowadź w pole tekstowe Nazwa Name nazwę, jaką chcesz nadać aplikacji. Naciśnij OK. Od tej pory dysponujesz aplikacją ASP. Wszystkie strony ASP w obrębie aplikacji mogą dzielić między sobą informacje przy użyciu obiektów Application i Session
Rysunek 8.3. Tworzenie aplikacji ASP
Sesja, w terminologii ASP, odnosi się do przemierzania przez określonego gościa twojej aplikacji. Sesja rozpoczyna się w momencie, gdy gość przegląda jedną ze stron ASP twojej aplikacji lub przechodzi do strony HTML, której kod wywołuje którąś z twoich stron ASP. Trwa ona dopóki odwiedzający nie opuści twej witryny.
Sesja określonego gościa witryny może być zakończona w sposób ukryty lub jawny. Kończy się ona w sposób ukryty, gdy gość nie żądał dostępu do strony na ustalony z góry czas trwania w minutach. Kończy się w sposób jawny, gdy wywołujesz metodę zakańczającą sesję gościa.
Podczas gdy odwiedzający przemierza twoją witrynę, możesz użyć obiektu Session w celu zapamiętania informacji o gościu oraz kontrolowania pewnych aspektów jego sesji. Obiekt Session zawiera zbiory, właściwości oraz metody zapewniające realizację tego typu funkcji w kodzie.
Obiekt Session posiada dwa zbiory, których możesz wykorzystać do kontrolowania danych używanych w stanie sesji. Zbiory te omówione są poniżej, a podsumowano je w tabeli 8.1.
Tabela 8.1. Zbiory obiektu Session
Zbiór |
Opis |
Contents |
Zbiór wszystkich zmiennych dostępnych na poziomie sesji, wyłączając te tworzone ze znacznikiem Object |
StaticObjects |
Zbiór wszystkich obiektów poziomu sesji, które utworzone były przy użyciu znacznika Object w pliku global.asa. |
Zbiór Contents jest grupą zmiennych, którą tworzysz w celu udostępnienia ich we wszystkich stronach aplikacji ASP poprzez obiekt Session. Zmienne obejmują swym zasięgiem poziom sesji, są więc dostępne dla dowolnej strony ASP, ale ich wartości nie są użytkowane przez wszystkich gości. Każdy gość będzie dysponował własną kopią zmiennej.
Ustalenia wartości dla pozycji zbioru Contents dokonujesz w następujący sposób:
Session.Contents("EmpName") = "Tonya"
Ponieważ jednak zbiór ten jest zbiorem domyślnym, możesz również napisać to samo w następujący sposób:
Session("EmpName") = "Tonya"
Każdy ze sposobów, wyszukujący lub ustalający wartość danej pozycji zbioru Contents, rozpoczyna się obiektem Session. Później pojawia się w cudzysłowie (jako że jest to pozycja zbioru) nazwa pozycji, do której chcesz się odnieść.
Ponieważ zmienne są pozycjami zbioru, to w odróżnieniu od standardowych zmiennych, nie wykorzystują instrukcji Option Explicit. Jej użycie w tym wypadku nie ma sensu, ponieważ najpierw możesz stworzyć zmienną w jednej stronie, a potem odwoływać się do niej na innych stronach. I takie jest rzeczywiste przeznaczenie zmiennych zbioru Contents - mają być wyszukiwane i ustawiane w wielu stronach twojej witryny WWW.
Na przykład mógłbyś w stronie zawrzeć następujący kod tworzący kilka zmiennych sesji:
<%
Session("UserName") = "Bob Tyler"
Session("UserID") = 10
Session("City")
= "
%>
Tworzymy tutaj trzy zmienne sesji, które od tej pory dostępne są dla każdej strony naszej aplikacji ASP. Po pierwsze tworzymy zmienną sesji o nazwie UserName i ustalamy dla niej wartość w postaci ciągu "Bob Tyler"
Session("UserName") = "Bob Tyler"
Wartość tą ustalamy wpisując ciąg, ale może być ona określona przez odwołanie się do wartości w bazie danych lub może zostać odebrana od użytkownika poprzez zbiór Form obiektu Request
Następnie tworzona jest zmienna o nazwie UserID, dla której ustalamy wartość 10. Zapamiętaj, że uzupełniając wartości zmiennych sesji możemy użyć ciągów, liczb, a także dat:
Session("UserID") = 10
W końcu ustalamy trzecią zmienną sesji, City, w której przechowujemy wartość "Portland"
Session("City")
= "
Teraz w kolejnej stronie możemy odwołać się do tych zmiennych sesji lub możemy stworzyć nowe. Spójrz na poniższy kod:
<%
If
Session("City") = "
Session("City") = "
End If
Response.Write "Cześć: " & Session("UserName") & ".<P>"
Response.Write "Twój numer to : " _
& Session("UserID") & ".<P>"
Response.Write "Co ciekawego w " & Session("City") & "?<P>"
%>
Po pierwsze wyszukujemy wartość zmiennej sesji City przy użyciu instrukcji If aby się przekonać, czy znajduje się w niej ciąg "Portland"
If
Session("City") = "
Jeśli tak, ustalamy nową wartość zmiennej:
Session("City")
= "
Następnie wykorzystujemy wartość zmiennej sesji UserName w metodzie Write
Response.Write "Cześć: " & Session("UserName") & ".<P>"
Wartości zmiennych UserID i City używane są jako dodatkowe wyjście dla przeglądarki:
Response.Write "Twój numer to : " _
& Session("UserID") & ".<P>"
Response.Write "Co ciekawego w " & Session("City") & "?<P>"
Wyjście kodu przedstawia rysunek 8.4.
Rysunek 8.4. Wyjście kodu wykorzystującego zbiór Contents
Możesz również tworzyć obiekty zbioru Contents. Jest to trochę niebezpieczne, ponieważ zasoby używane przez obiekty mogą być znacznie większe od prostych zmiennych, ale pozwala to na stworzenie obiektu Session w jednym miejscu, a następnie korzystanie z niego w całej twojej aplikacji ASP.
Przykładowo możesz stworzyć na stronie kopię obiektu:
set Session("Sconn") = Server.CreateObject("adodb.connection")
Ten obiekt Session jest teraz utworzony i używa zasobów systemowych odpowiednich dla swojego typu. W kolejnej stronie lub stronach możesz pisać kody używając przy tym obiektu Session
Session("Sconn").open "ASPBook", "sa", "yourpassword"
Ponieważ te pola są częścią zbioru, możemy użyć bloku For...Each do przejścia kolejno przez każdą zmienną sesji lub obiekt. Kod bloku jest następujący:
<%
For Each MySession in Session.Contents
Response.Write "Punkty sesji: " & MySession & "<P>"
Next
%>
Wyjście kodu, stworzone na podstawie wszystkich zdefiniowanych do tej pory zmiennych, pokazano na rysunku 8.5.
Rysunek 8.5. Wyświetlanie punktów sesji przy użyciu zbioru Contents
Pomyśl o przepływie kodu w stronie, gdzie najpierw do zmiennej sesji City wpisujemy ciąg "Portland", a następnie w kolejnej stronie zmieniamy tą wartość na "Portland, stan Oregon". Jeśli gość wróciłby na pierwszą stronę, wartość zmiennej znowu zostałaby ustawiona na "Portland". Wiele razy będziesz dysponował kodem, który stworzy te zmienne sesji i nada im początkową wartość. Jeśli jednak zmienne te były już wcześniej utworzone, nie chcesz zmieniać ich wartości. Możesz wykorzystać funkcję IsEmpty w celu określenia, czy zmienna sesji już istnieje.
Tak więc nasz kod moglibyśmy zmodyfikować w następujący sposób:
<%
If IsEmpty(Session("City")) Then
Session("City") = "
End If
%>
Teraz kod zadziała tylko raz w czasie sesji gościa. Po utworzeniu zmiennej sesji warunek instrukcji If nie będzie prawdą, więc zmienna nie będzie przydzielona ponownie. W dalszej części rozdziału zwrócimy uwagę na jeszcze jeden sposób inicjalizacji zmiennych sesji - poprzez plik global.asa.
Kolejnym zastosowaniem zmiennych sesji jest wymuszenie na gościach, aby najpierw weszli na określoną stronę przed odwiedzeniem jakiejś innej strony. Załóżmy na przykład, że dysponujesz na twojej witrynie WWW quizami dla klasy, którą uczysz. Przed rozpoczęciem quizu goście będą musieli się zalogować. Problemem, z którym się spotkasz jest fakt, że uczniowie ustawią znacznik w samym quizie i w ten sposób będą powracać wprost do tej strony z pominięciem logowania.
Aby z tym sobie poradzić możesz wykorzystać zmienną sesji. Mogłaby ona zawierać numer identyfikacyjny ucznia i nosić nazwę StudentID, a ustawiana byłaby jedynie w stronie logowania. Sama strona quizu zawierałaby kod podobny do tego przedstawionego poniżej, który zapobiegałby wchodzeniu na stronę z pominięciem strony logowania:
<%
If IsEmpty(Session("StudentID")) then
Response.Redirect "./login.asp"
End If
%>
Teraz, gdy uczniowie będą próbować wejścia wprost na stronę quizu bez logowania, zmienna sesji StudentID będzie pusta i uczniowie będą readresowani do strony logowania.
W dalszej części tego rozdziału omówimy plik global.asa w całej rozciągłości. W tym momencie powinieneś wiedzieć, że jest on częścią aplikacji ASP. Daje on możliwość napisania kodu, który uruchamiany jest na początku lub pod koniec sesji gościa. Ponadto plik umożliwia napisanie kodu uruchamianego w chwili rozpoczęcia bądź zakończenia działania aplikacji ASP.
Możesz również stworzyć obiekty Session w pliku global.asa, które później dostępne są - jak te omówione do tej pory - dla wszystkich stron znajdujących się w obrębie aplikacji ASP. Obiekty te tworzysz przy użyciu znacznika Object, a stają się one dostępne dzięki zbiorowi StaticObjects
Takie statyczne obiekty sesji są deklarowane w pliku global.asa poprzez znacznik Object w następujący sposób:
<OBJECT RUNAT=Server SCOPE=Session ID=Sconn PRODIG="adodb.connection">
</OBJECT>
Ten wiersz kodu tworzy obiekt zasięgu sesji o nazwie Sconn, który jest obiektem połączenia ADO. Ten natomiast:
<OBJECT RUNAT=Server SCOPE=Session ID=SobjMail PRODIG="CDONTS.
NewMail">
</OBJECT>
tworzy obiekt sesji o nazwie SobjMail, który jest obiektem CDO używanym do wysyłania wiadomości e-mail.
Po utworzeniu obiektów możesz odwoływać się do każdego z nich w kodzie dowolnej strony ASP będącej częścią aplikacji, tak jak tutaj:
<%
Option Explicit
Dim RSUser
Sconn.open "ASPBook", "sa", "yourpassword"
set RSUser = Sconn.Execute("select * from Users")
%>
Najważniejsze rzeczą, na którą powinieneś zwrócić uwagę jest to, że do zbioru StaticObjects odnosimy się inaczej niż do zbioru Contents. Po prostu określamy nazwę pozycji zbioru bez wcześniejszego podawania obiektu. W tym przykładzie właśnie w ten sposób używamy nazwy obiektu Sconn
Sconn.open "ASPBook", "sa", "yourpassword"
Ponieważ są to pozycje zbioru, możemy użyć bloku For...Each, aby przejść kolejno przez wszystkie te pozycje:
<%
Option Explicit
Dim MySessionSO
For Each MySessionSO in Session.StaticObjects
Response.Write "Obiekt statyczny: & MySessionSO & "<P>"
Next
%>
Po pierwsze informujemy kompilator o zamiarze deklaracji naszych zmiennych:
Option Explicit
Następnie deklarujemy zmienną, która będzie przechowywała odwołanie do każdego obiektu zbioru StaticObjects
Dim MySessionSO
Blok For...Each rozpoczyna swe działanie i przechodzi w pętli kolejno przez wszystkie pozycje zbioru:
For Each MySessionSO in Session.StaticObjects
Metoda Write obiektu Response wpisuje nazwę obiektu statycznego do przeglądarki przed przejściem do kolejnego obiektu zbioru:
Response.Write "Obiekt statyczny: & MySessionSO & "<P>"
Next
Wyjście kodu, wyświetlającego nazwę dwóch stworzonych przez nas obiektów, pokazano na rysunku 8.6.
Rysunek 8.6. Wyjście kodu wykorzystującego zbiór StaticObjects
Właściwości obiektu Session pozwalają na konfigurację, a następnie odnoszenie się do aspektów sesji gościa. Omówiono je w tym podrozdziale oraz podsumowano w tabeli 8.2.
Tabela 8.2. Właściwości obiektu Session
Właściwość |
Przeznaczenie |
CodePage |
Określa zestaw znaków używany w sesji. |
LCID |
Definiuje identyfikator lokalizacji dla sesji. |
SessionID |
Definiuje unikalny identyfikator dla sesji gościa. |
TimeOut |
Określa czas w minutach pomiędzy kolejnymi żądaniami dostępu do strony, który nie może zostać przekroczony, w innym wypadku sesja gościa będzie traktowana jako zakończona. |
Właściwość CodePage pozwala na wybór zestawu znaków, który będzie używany w czasie trwania sesji. Zestaw obejmuje liczby, litery, a także inne znaki. Zestawy znaków różnią się między sobą w zależności od kraju, w którym obowiązują, możesz więc użyć tej właściwości jeśli chcesz umieścić na twojej witrynie zawartość międzynarodową.
CodePage jest właściwością sesji, tak więc jej ustawienia będą obowiązywały we wszystkich stronach twojej aplikacji ASP. Właściwość tą wpisywać i odczytywać, a przyjmuje ona następującą formę:
Session.CodePage = CPValue
gdzie CPValue jest liczbą odnoszącą się do strony kodowej, której chcesz użyć. Spójrz na ten kod:
<%
Session.CodePage = 1252
Response.Write "Używana strona kodowa: " & Session.CodePage & "<P>"
Response.Write "1é ć ç ę ë ě í î ď đ Ę Î Đ" & "<P>"
Session.CodePage = 932
Response.Write " Używana strona kodowa: " & Session.CodePage & "<P>"
Response.Write "1é ć ç ę ë ě í î ď đ Ę Î Đ" & "<P>"
%>
Po pierwsze, ustalamy angielską stronę kodową dla całej sesji:
Session.CodePage = 1252
Następnie wartość strony kodowej wpisywana jest do przeglądarki:
Response.Write "Używana strona kodowa: " & Session.CodePage & "<P>"
Teraz wpisywane do przeglądarki niektóre niestandardowe znaki:
Response.Write "1é ć ç ę ë ě í î ď đ Ę Î Đ" & "<P>"
W kolejnym wierszu kodu ustawiana jest japońska strona kodowa:
Session.CodePage = 932
Do przeglądarki wpisywana jest wartość właściwości CodePage
Response.Write "Używana strona kodowa: " & Session.CodePage & "<P>"
jak również ponownie niektóre znaki niestandardowe:
Response.Write "1é ć ç ę ë ě í î ď đ Ę Î Đ" & "<P>"
Właściwość LCID obiektu Session pozwala na określenie sposobu dynamicznego wyświetlania tekstu w zależności od lokalizacji. Dotyczy ona wyświetlania takich rzeczy jak czas, liczby oraz waluta.
Ponieważ jest to właściwość sesji, raz ustawiona obowiązuje dla wszystkich stron twojej aplikacji ASP. Właściwość tą można zapisywać i odczytywać, a przyjmuje ona następującą formę:
Session.LCID = LocaleID
gdzie LocaleID jest liczbą typu long reprezentującym daną lokalizację.
Właściwość ta dostarcza dodatkowego mechanizmu internacjonalizacji twojej witryny. Używasz jej w celu właściwego sformatowania zawartości twojej strony. Zwróć uwagę na przykładowy blok kodu:
<%
Session.LCID = 1033
Response.Write "Format amerykański: " & Now & " " _
& formatcurrency(1234.56) & "<P>"
Session.LCID = 2057
Response.Write "Format brytyjski : " & Now & " " _
& formatcurrency(1234.56) & "<P>"
Session.LCID = 1049
Response.Write "Format rosyjski: " & Now & " " _
& formatcurrency(1234.56) & "<P>"
Session.LCID = 1032
Response.Write "Format grecki: " & Now & " " _
& formatcurrency(1234.56) & "<P>"
Session.LCID = 2049
Response.Write "Format iracki: " & Now & " " _
& formatcurrency(1234.56) & "<P>"
Session.LCID = 3073
Response.Write "Format egipski: " & Now & " " _
& formatcurrency(1234.56) & "<P>"
Session.LCID = 6154
Response.Write "Format panamski: " & Now & " " _
& formatcurrency(1234.56) & "<P>"
%>
Pierwszą ustawioną przez kod lokalizacją są Stany Zjednoczone:
Session.LCID = 1033
Następnie kod wyświetla aktualną datę i godzinę, jak również walutę w formacie obowiązującym w Stanach Zjednoczonych:
Response.Write "Format amerykański: " & Now & " " _
& formatcurrency(1234.56) & "<P>"
Tutaj ustawioną lokalizacją jest Wielka Brytania:
Session.LCID = 2057
a następnie wyświetlana jest data, godzina oraz waluta w formacie brytyjskim:
Response.Write "Format brytyjski : " & Now & " " _
& formatcurrency(1234.56) & "<P>"
Podobnie kod wyświetla format rosyjski:
Session.LCID = 1049
Response.Write "Format rosyjski: " & Now & " " _
& formatcurrency(1234.56) & "<P>"
Następnie format grecki:
Session.LCID = 1032
Response.Write "Format grecki: " & Now & " " _
& formatcurrency(1234.56) & "<P>"
Tutaj iracki:
Session.LCID = 2049
Response.Write "Format iracki: " & Now & " " _
& formatcurrency(1234.56) & "<P>"
Następne wyświetlany jest egipski format daty, godziny i waluty:
Session.LCID = 3073
Response.Write "Format egipski: " & Now & " " _
& formatcurrency(1234.56) & "<P>"
To samo jeśli chodzi o format panamski:
Session.LCID = 6154
Response.Write "Format panamski: " & Now & " " _
& formatcurrency(1234.56) & "<P>"
Wyjście kodu zaprezentowano na rysunku 8.7.
Rysunek 8.7. Wyjście kodu wykorzystującego właściwość LCID
Serwer IIS musi mieć sposoby na wewnętrzne śledzenie przechodzenia gości przez twoją witrynę. Jednym z takich sposobów jest wykorzystanie właściwości SessionID. Kiedy używasz aplikacji ASP, serwer IIS przydziela losową liczbę typu long wszystkim gościom wchodzącym na twoją witrynę.
Właściwość ta służy tylko do odczytu, ponieważ jest używana wewnętrznie przez serwer IIS w celu identyfikacji wszystkich gości podczas trwania ich sesji. Właściwość ma następującą składnię:
TheID = Session.SessionID
TheID jest zmienną, w której chcesz umieścić numer identyfikacyjny.
Przypis
SessionID nie jest niepowtarzalnym numerem przez cały czas. Jeśli ponownie uruchomisz swój serwer, to ten sam numer może być przydzielony ponownie. Nie używaj więc tego identyfikatora jako klucza głównego tabeli.
Sesja rozpoczyna się w chwili, gdy gość uzyskuje dostęp do jednej ze stron aplikacji ASP lub gdy uzyskuje dostęp do strony wywołującej kod jednej z twoich stron ASP. Jednym z sposobów, w jaki sesja może się skończyć to brak żądania dostępu gościa do strony twojej aplikacji ASP w pewnym określonym (w minutach) zakresie czasu. Ilość minut ustalana jest przez właściwość TimeOut. Właściwość ta może być zapisywana i odczytywana, a zapamiętuje ona czas w minutach, jaki może upłynąć pomiędzy kolejnymi żądaniami dostępu do aplikacji ASP bez jej przeterminowania.
Domyślna wartość tej właściwości jest ustawiana przez Konsolę zarządzania Microsoftu serwera IIS. Przejdź do twojej aplikacji ASP i wybierz Właściwości Properties . Następnie przejdź do zakładki Katalog Directory i naciśnij przycisk Konfiguracja Configuration). Przejdź do zakładki Opcje aplikacji App Options , a wtedy powinieneś ujrzeć dialog, który został zaprezentowany na rysunku 8.8.
Rysunek 8.8. Ustawianie domyślnej wartości właściwości TimeOut
Pole tekstowe Czas trwania sesji Session TimeOut zawiera domyślną wartość właściwości TimeOut. Możesz unieważnić tą wartość w kodzie przy użyciu właściwości TimeOut. Właściwość może być zapisywana lub odczytywana i przyjmuje następujący format:
Session.TimeOut = NumMinutes
gdzie NumMinutes jest ilością minut pomiędzy żądaniami dostępu, których upłynięcie powoduje zakończenie sesji.
Kiedy sesja się kończy, wszystkie jej obiekty i zmienne zostają uwolnione i ich wartości przestają być dostępne. Jeśli goście żądają dostępu do strony po przekroczeniu czasu ważności, będzie to zinterpretowane jako pierwsze żądanie, co spowoduje rozpoczęcie nowej sesji.
Obiekt Session posiada jedną tylko metodę, która pozwala na podjęcie działania w związku z tym obiektem. Metoda ta jest omówiona poniżej, a podsumowuje ją tabela 8.3.
Tabela 8.3. Metoda Obiektu Session
Metoda |
Przeznaczenie |
Abandon |
Jawne zakończenie sesji odwiedzającego. |
Jak to było widać w ostatnim podrozdziale, sesje gości kończą się po upłynięciu pomiędzy żądaniami ustalonego czasu mierzonego w minutach. Innym sposobem na zakończenie sesji jest wywołanie w kodzie metody Abandon
Metoda Abandon obiektu Session pozwala na natychmiastowe zakończenie sesji gościa. Jest to pomocne sytuacjach, gdy goście podejmują działanie kończące jakiś proces, w który byli zaangażowani. Na przykład, jeśli masz witrynę e-commerce, goście mogą przeszukiwać katalog twoich produktów i umieszczać niektóre z nich w koszyku. Aby zarządzać ich stanem używasz obiektu Session wraz z identyfikatorem klienta, tak więc mogą oni dokładać produkty do koszyka oraz usuwać je stamtąd - a ty przez cały czas utrzymujesz ich stan. W którymś momencie mogą oni opuścić twój sklep online. Kiedy podejmą takie działanie oznacza to, że zakończyli swe zakupy, a ty powinieneś przetworzyć ich zamówienie. Musisz zakończyć ich sesję. Dokonasz tego przy użyciu metody Abandon
Metoda Abandon ma następującą składnię:
Session.Abandon
Spójrz na przykład na ten kod:
<%
Session("UserName") = "Jim Smith"
Response.Write Session("UserName")
Session.Abandon
%>
Tutaj tworzona jest zmienna sesji o nazwie UserName
Session("UserName") = "Jim Smith"
Wartość tej zmiennej jest wpisywana do przeglądarki:
Response.Write Session("UserName")
Sesja kończy się:
Session.Abandon
Kiedy już wykonywanie kodu strony jest zakończone, zmienna sesji przestaje być dostępna. Kiedy wywołana zostaje metoda Abandon, uruchamiane jest zdarzenie Session_OnEnd i wszystkie zmienne sesji oraz obiekty zostają uwolnione.
Jak mogłeś się nauczyć z tego rozdziału, aplikacja ASP jest połączeniem stron ASP oraz pliku global.asa we wspólnej strukturze katalogu. Obiekt Application pozwala na programową kontrolę twojej aplikacji.
Przy użyciu metod i zbiorów dostępnych w obrębie tego obiektu, możesz tworzyć zmienne i obiekty widziane w całej aplikacji w czasie trwania wszystkich sesji, jak również metody pozwalające na kontrolę zmian stanu zmiennych.
Obiekt Application ma dwa zbiory, które możesz wykorzystać do kontroli zmiennych i obiektów widzianych w całej aplikacji ASP. Zbiory te omówiono poniżej, a sumarycznie prezentuje je tabela 8.4.
Tabela 8.4. Zbiory obiektu Application
Zbiór |
Opis |
Contents |
Zbiór wszystkich zmiennych dostępnych na poziomie aplikacji, wyłączając te tworzone ze znacznikiem Object |
StaticObjects |
Zbiór wszystkich obiektów poziomu aplikacji, które utworzone były przy użyciu znacznika Object w pliku global.asa. |
Zbiór Contents jest grupą zmiennych, którą udostępniasz każdej ze stron twojej aplikacji ASP w czasie trwania dowolnej sesji. Zmienne te mają zasięg aplikacji, są więc dostępne dla każdej strony ASP i nie są współużytkowane przez wszystkich gości. Kod uruchamiany z osobna dla każdego gościa odwołuje się do tego samego zbioru zmiennych aplikacji.
Ustalenia wartości danej pozycji zbioru Contents dokonuje się w następujący sposób:
Application.Contents("CurrentDiscount") = .9
Składnia polecenia, zarówno dla ustawiania, jak i wyszukiwania pozycji zbioru Contents rozpoczyna się słowem Application, a następnie w cudzysłowie (ponieważ jest to pozycja zbioru) określana jest nazwa pozycji, do której się odwołujesz.
Podobnie jak zbiór Contents obiektu Session, również zbiór obiektu Application nie wywoła stanu błędu związanego z użyciem instrukcji Option Explicit, jeśli zmienna nie była wywoływana wcześniej. Jest to w pełni zrozumiałe, ponieważ sednem użycia zbioru Contents w dowolnym obiekcie jest tworzenie zmiennych dostępnych w obrębie szerszej ilości stron.
Zmienne aplikacji dostarczają mechanizmu tworzenia i ustalania wartości zmiennych w jednym położeniu, do których następnie będzie można się odwoływać w wielu innych miejscach. Dzięki temu można modyfikować kod w prostszy sposób. Weźmy następujący przykład:
<%
Application("CurrentDiscount") = .9
Application("MinShipHand") = 12
Application("MinQuantity") = 2
Application("ShipHandPercent") = .07
%>
Utworzyliśmy tutaj cztery zmienne aplikacji. Ich wartości będą dostępne dla wszystkich stron aplikacji ASP w czasie trwania każdej sesji.
Pierwsza utworzona zmienna nosi nazwę CurrentDiscount, a przypisujemy wartość 0.9:
Application("CurrentDiscount") = .9
Następnie tworzona jest zmienna MinShipHand, która zapamiętuje minimalną płatność za transport i obsługę przy realizacji jednego zamówienia, wynoszącą w tym wypadku 12 dolarów:
Application("MinShipHand") = 12
Trzecia zmienna aplikacji, MinQuantity, zapamiętuje minimalną ilość kupowanych produktów:
Application("MinQuantity") = 2
I wreszcie czwarta zmienna aplikacji, ShipHandPercent, przechowuje naliczany procent za transport i obsługę:
Application("ShipHandPercent") = .07
Teraz możemy odwoływać się do tych zmiennych w innych stronach aplikacji ASP:
<%
Option Explicit
Dim OrderTotal
Dim SandH
Dim TotalDue
OrderTotal = Session("OrderTotal") * Application("CurrentDiscount")
SandH = OrderTotal * Application("ShipHandPercent")
If SandH < Application("MinShipHand") Then
SandH = Application("MinShipHand")
End If
TotalDue = SandH + OrderTotal
%>
Ten prosty blok kodowy jest przykładem sposobu obliczenia całkowitej sumy zamówienia. Zauważ, że nie ma w tym kodzie na sztywno zakodowanych liczb. Kod wykorzystuje zmienne aplikacji w celu określenia opłaty.
Wstępnie jednak kompilator zostaje poinformowany o deklaracji naszych zmiennych:
Option Explicit
Następnie tworzymy zmienną zapamiętującą sumę zamówienia podlegającą zniżce:
Dim OrderTotal
Następna tworzymy zmienną zapamiętującą kwotę należną za transport i obsługę:
Dim SandH
oraz ostatnią zmienną, przechowującą ostateczną kwotę do zapłaty:
Dim TotalDue
Suma zamówienia jest obliczana przy użyciu zapamiętanej zniżki w zmiennej aplikacji CurrentDiscount
OrderTotal = Session("OrderTotal") * Application("CurrentDiscount")
Następnie należna kwota za transport i obsługę obliczana jest jako określony w zmiennej aplikacji ShipHandPercent procent wartości zmiennej OrderTotal
SandH = OrderTotal * Application("ShipHandPercent")
Mamy również określoną minimalną płatność za transport i obsługę. Instrukcja If porównuje płatność bieżącą z jej wartością minimalną, zapisaną w zmiennej aplikacji:
If SandH < Application("MinShipHand") Then
Jeśli obliczona płatność za transport i obsługę jest mniejsza od wartości minimalnej, do zmiennej wpisywana jest ta wartość minimalna:
SandH = Application("MinShipHand")
End If
W końcu obliczana jest kwota do zapłaty, będąca sumą należności ze zniżką oraz płatności za transport i obsługę:
TotalDue = SandH + OrderTotal
Możesz również tworzyć obiekty zbioru Contents, ale tutaj bądź bardzo ostrożny. Pamiętaj, że zmienne aplikacji oraz obiekty utrzymują się przez cały czas trwania aplikacji ASP, więc wszystkie zasoby wykorzystywane przez obiekt będą również w użyciu przez cały czas, a ten może okazać się bardzo długi.
Kiedy tworzysz obiekt obejmujący zasięgiem aplikację, podobny do tego:
Set Application("Gconn") = Server.CreateObject("adodb.connection")
przemyśl to, co będzie realizował ten wiersz kodu. Przez cały czas trwania twojej aplikacji, który wynieść może tygodnie, utrzymywałbyś stałe połączenie z bazą danych.
Ponieważ Contents jest zbiorem, możemy przejść kolejno przez wszystkie jego pozycje korzystając z następującego kodu:
<%
Option Explicit
Dim MyApp
For Each MyApp in Application.Contents
Response.Write "Nazwa zmiennej aplikacji: " & MyApp _
& " Wartość: " & Application(MyApp) & "<P>"
Next
%>
Po pierwsze, sygnalizujemy zamiar deklarowania zmiennych:
Option Explicit
Następnie deklarujemy zmienną, która będzie zapamiętywała odwołanie do każdej pozycji zbioru podczas przechodzenia przez pętlę:
Dim MyApp
Później nasz blok For...Each przechodzi kolejno przez wszystkie pozycje zbioru Contents
For Each MyApp in Application.Contents
Do przeglądarki wpisywana jest nazwa każdej zmiennej aplikacji wraz z wartością:
Response.Write "Nazwa zmiennej aplikacji: " & MyApp _
& " Wartość: " & Application(MyApp) & "<P>"
Następnie kod przechodzi w pętli do kolejnej pozycji zbioru:
Next
Wyjście omówionego wcześniej, przykładowego kodu przetwarzającego kwotę zamówienia zaprezentowano na rysunku 8.9.
Rysunek 8.9. Wyjście kodu przechodzącego przez pozycje zbioru Contents
Podobnie jak obiekt Session, również obiekt Application posiada zbiór StaticObjects, który jest tworzony poprzez plik global.asa. Pamiętaj, że plik ten jest częścią aplikacji ASP. Daje on możliwość napisania kodu, który uruchamiany jest w chwili rozpoczęcia bądź zakończenia działania aplikacji ASP. Ponadto plik umożliwia napisanie kodu uruchamianego na początku lub pod koniec sesji.
Takie obiekty tworzysz przy użyciu znacznika Object, a stają się one dostępne poprzez zbiór StaticObjects. Deklarujemy je w pliku global.asa w następujący sposób:
<OBJECT RUNAT=Server SCOPE=Application ID=Gconn PRODIG=
"adodb.connection">
</OBJECT>
Powyższy wiersz kodu tworzy obiekt o zasięgu aplikacji o nazwie Gconn, który jest obiektem połączenia ADO. Po utworzeniu obiektu możesz odnosić się do pozycji zbioru StaticObjects w każdej ze stron aplikacji ASP w czasie trwania dowolnej sesji:
<%
Option Explicit
Dim RSUser
Gconn.open "ASPBook", "sa", "yourpassword"
set RSUser = Sconn.Execute("select * from Users")
%>
Zauważ, że sposób odwołania się do zbioru StaticObjects różni się od sposobu odwoływania się do zbioru Contents. Nazwa pozycji zbioru określana jest bez poprzedzenia jej jakimkolwiek obiektem. W tym przykładzie po prostu używana jest nazwa obiektu Gconn
Gconn.open "ASPBook", "sa", "yourpassword"
Możesz również użyć bloku For...Each w celu przejścia kolejno przez wszystkie pozycje zbioru StaticObjects
<%
Option Explicit
Dim MyAppSO
For Each MyAppSO in Application.StaticObjects
Response.Write "Obiekt aplikacji: " & MyAppSO & "<P>"
Next
%>
Po pierwsze pojawia się instrukcja Option Explicit, jak tego wymaga deklaracja zmiennych:
Option Explicit
Następnie tworzona jest zmienna, która będzie zapamiętywała odwołanie do pozycji zbioru:
Dim MyAppSO
Później rozpoczynamy iterację w strukturze bloku For.Each
For Each MyAppSO in Application.StaticObjects
Do przeglądarki wpisywana jest nazwa pozycji zbioru StaticObjects
Response.Write "Obiekt aplikacji: " & MyAppSO & "<P>"
Next
Obiekt Application posiada dwie metody, których używa w celu kontrolowania odwołań do pozycji zbioru Contents. Zostały one omówione w tym podrozdziale, a sumarycznie przedstawia je tabela 8.5.
Tabela 8.5. Metody obiektu Application
Metoda |
Przeznaczenie |
Lock |
Blokuje zmienną aplikacji tak, aby inne sesje nie mogły jej modyfikować. |
Unlock |
Uwalnia blokadę zmiennych aplikacji. |
Jednym z problemów pojawiających się przy dużej zajętości witryny lub nawet w wypadkach gdy ruch nie jest aż tak wielki, jest możliwość modyfikacji zmiennych aplikacji przez większą ilość skryptów w jednym czasie. Pamiętaj, że zmienna poziomu aplikacji jest dostępna dla wszystkich sesji. Jeśli więc obsługujesz setki równoczesnych sesji staje się prawdopodobne, że więcej niż jedna z nich będzie próbowała zmienić wartość zmiennej aplikacji w tym samym czasie.
Na przykład możesz śledzić liczbę udanych wywołań strony przy użyciu zmiennej aplikacji. Kiedy aplikacja jest uruchamiana, mógłbyś ustawić początkową wartość zmiennej według jakiegoś pola bazy danych, używając przy tym kodu podobnego do tego:
<%
Option Explicit
Dim conn
Dim RSPageHits
set conn = server.createobject ("adodb.connection")
conn.open "ASPBook", "sa", "yourpassword"
set RSPageHits = conn.Execute("select Hits from RSPageHits")
Application("PageHits") = RSPageHits("Hits")
%>
Wymagana jest deklaracja zmiennych:
Option Explicit
Tworzona jest zmienna zapamiętująca połączenie z bazą danych:
Dim conn
Następnie tworzymy kolejną zmienną, która będzie wyszukiwała w bazie danych informacje o udanych wywołaniach:
Dim RSPageHits
Zmienna Conn będzie spełniała rolę obiektu Connection
set conn = server.createobject ("adodb.connection")
Zestawiane jest połączenie bazą danych:
conn.open "ASPBook", "sa", "yourpassword"
Zapytanie wyszukuje w bazie dane o udanym wywołaniu:
set RSPageHits = conn.Execute("select Hits from RSPageHits")
Tworzona jest zmienna aplikacji PageHits, zapamiętującą liczbę udanych wywołań strony:
Application("PageHits") = RSPageHits("Hits")
Teraz, za każdy razem kiedy strona jest wywoływana, zmienna aplikacji PageHits jest inkrementowana:
<%
Application("PageHits") = Application("PageHits") + 1
%>
Tu spotykamy się z sednem problemu. Jeśli wielu gości uzyska dostęp do strony równocześnie, istnieje możliwość, że więcej niż jedna sesja będzie próbowała zmienić wartość zmiennej aplikacji w tym samym czasie. Metoda Lock radzi sobie z tego typu problemami blokując zmienne aplikacji tak, aby w jednym czasie tylko jedna sesja mogła zmodyfikować ich wartość. Metoda ma następującą składnię:
Application.Lock
Możemy zmodyfikować nasz kod zawierając w nim metodę Lock, dając w ten sposób możliwość zmiany wartości zmiennej tylko jednej sesji naraz:
<%
Application.Lock
Application("PageHits") = Application("PageHits") + 1
%>
W tym przypadku wszystkie zmienne aplikacji zostaną zablokowane, dopóki kompilator nie zakończy przetwarzania kodu strony. Jak się jednak przekonasz, kolejna metoda uwalnia blokadę.
Istnieją dwa sposoby zwolnienia blokady zmiennych aplikacji. O pierwszej z nich już wspomnieliśmy: pozwolić kodowi działać aż do końca, a wtedy blokada zostanie zwolniona. Jeśli jednak przetworzenie kodu zabiera zbyt dużo czasu, możesz zakończyć je uwalniając zmienne aplikacji, na które oczekują inne sesje. Z tego powodu powinieneś zablokować twoje zmienne aplikacji przed ich modyfikacją i uwolnić je po modyfikacji.
Zwolnienia blokady dokonuje się przy użyciu metody Unlock, która ma następującą składnię:
Application.Unlock
Powinniśmy więc zmodyfikować naszą przykładową stronę zliczającą udane wywołania, umieszczając w niej następujący, blokowany kod:
<%
Application.Lock
Application("PageHits") = Application("PageHits") + 1
Application.Unlock
%>
Tuż przed modyfikacją blokowane są zmienne aplikacji:
Application.Lock
Następnie dokonujemy modyfikacji zmiennej:
Application("PageHits") = Application("PageHits") + 1
Po dokonaniu zmian blokada jest zwalniana:
Application.Unlock
Do tej pory rozdział omawiał sposoby tworzenia aplikacji ASP. Przyjrzeliśmy się plikom składającym się na aplikację: plikom ASP oraz plikowi global.asa znajdującym się w strukturze tego samego katalogu. Zwróciliśmy uwagę na obiekty Session i Application oraz sposoby tworzenia zmiennych i obiektów dostępnych w obrębie całej aplikacji ASP.
W tej części rozdziału zajmiemy specjalnym plikiem używalnym przez aplikacje ASP, global.asa. Po pierwsze, jest to plik tekstowy. Możesz go utworzyć przy użyciu twego ulubionego edytora tekstu lub możesz w tym celu skorzystać z jednego z narzędzi rozbudowy stron.
Plik ten musi nosić nazwę global.asa i musi znajdować się w katalogu głównym aplikacji ASP. Składa się on z czterech zdarzeń, dla których możesz stworzyć procedury oraz ze znaczników Object
Struktura pliku global.asa przedstawia się następująco:
<OBJECT RUNAT=Server SCOPE=Application ID=Aconn PRODIG="adodb.
connection">
</OBJECT>
<OBJECT RUNAT=Server SCOPE=Session ID=SobjMail PRODIG="CDONTS.
NewMail">
</OBJECT>
<SCRIPT LANGUAGE="VBScript" RUNAT="Server">
Sub Application_OnStart
'kod procedury
End Sub
Sub Session_OnStart
'kod procedury
End Sub
Sub Session_OnEnd
'kod procedury
End Sub
Sub Application_OnEnd
'kod procedury
End Sub
</SCRIPT>
Na samym początku pliku znajdują się obiekty poziomu aplikacji, deklarowane przy użyciu znacznika Object
<OBJECT RUNAT=Server SCOPE=Application ID=Aconn PRODIG="adodb.
connection">
</OBJECT>
W drugiej kolejności mogą znaleźć się obiekty poziomu sesji, również tworzone przy użyciu znacznika Object
<OBJECT RUNAT=Server SCOPE=Session ID=SobjMail PRODIG="CDONTS.
NewMail">
</OBJECT>
Następnie znacznik Script wskazuje używany język programowania oraz na miejsce uruchamiania kodu:
<SCRIPT LANGUAGE="VBScript" RUNAT="Server">
Dalej możesz umieścić kod, który będzie uruchomiony w chwili wystąpienia określonego zdarzenia. Możesz stworzyć kod uruchamiany przy starcie aplikacji:
Sub Application_OnStart
'kod procedury
End Sub
Możesz stworzyć kod uruchamiany przy rozpoczęciu sesji:
Sub Session_OnStart
'kod procedury
End Sub
Poza tym kod działający na końcu sesji:
Sub Session_OnEnd
'kod procedury
End Sub
Oraz na końcu aplikacji:
Sub Application_OnEnd
'kod procedury
End Sub
Strona kończy się znacznikiem Script
</SCRIPT>
W obrębie pliku global.asa możesz stworzyć kod uruchamiany w różnych momentach trwania aplikacji ASP. Zdarzenia te omówiono poniżej, a sumarycznie przedstawia je tabela 8.6.
Tabela 8.6. Zdarzenia aplikacji i sesji
Zdarzenie |
Moment zadziałania |
Application_OnStart |
Zdarzenie uruchamiane w chwili żądania dostępu do pierwszej strony aplikacji ASP. |
Application_OnEnd |
Kod zdarzenia uruchamiany jest w chwili zamknięcia serwera IIS. |
Session_OnStart |
Uruchamiane w chwili, gdy dowolny gość wywołuje swoją pierwszą stronę aplikacji ASP. |
Session_OnEnd |
Kod procedury uruchamiany jest po upłynięciu czasu trwania sesji lub w chwili wywołania metody Abandon |
Struktura procedury zdarzenia przedstawia się następująco:
Sub NameOfEvent
'kod zdarzenia
End Sub
Pierwszy wiersz procedury rozpoczyna się słowem kluczowym Sub, po którym następuje nazwa procedury. W kolejnych wierszach zawarty jest kod uruchamiany w przypadku wystąpienia danego zdarzenia. Ostatni wiersz procedury zawiera kluczowe słowa End Sub
Kiedy odwiedzający żąda dostępu do strony twojej aplikacji ASP po raz pierwszy od uruchomienia serwera, zadziała zdarzenie Application_OnStart. Zdarzenie to jest uruchamiane przed jakimkolwiek innym kodem żądanej strony, jak również przed uruchomieniem zdarzenia Session_OnStart
Zdarzenie Application_OnStart uruchamiane jest tylko jeden raz i nie stanie się to ponownie, dopóki aplikacja nie zakończy swego działania. Kod tego zdarzenia może uzyskiwać dostęp do obiektów Application i Server. Obiekty Request Response i Session nie są osiągalne w tym wypadku.
Zdarzenie ma następującą składnię:
Sub Application_OnStart
'kod procedury
End Sub
Typowo zdarzenie to używane jest podczas inicjacji programu. Jest to kod, który chcesz uruchomić jeden tylko raz, przy starcie twojej aplikacji. Często wymaga to tworzenia zmiennych i obiektów aplikacji. To zdarzenie jest wykorzystywane również przez kod powiadomienia.
We wcześniejszej części rozdziału zwróciliśmy uwagę na stronę obliczającą całkowitą należność za zamówienie. Kod używał zmiennych aplikacji deklarowanych w stronie ASP w celu określenia całkowitej kwoty zamówienia. Te zmienne powinny być inicjowane w zdarzeniu Application_OnStart
Sub Application_OnStart
Application("CurrentDiscount") = .9
Application("MinShipHand") = 12
Application("MinQuantity") = 2
Application("ShipHandPercent") = .07
End Sub
Nie musimy martwić się tutaj o blokowanie zmiennych aplikacji, ponieważ zdarzenie to jest uruchamiane i działa przed jakimkolwiek innym kodem aplikacji ASP.
Kolejnym dobrym przykładem zastosowania tego zdarzenia jest dostosowywanie programu do potrzeb użytkownika. Powiedzmy, że tworzysz aplikację ASP, która używana będzie przez wiele organizacji. Chcesz dostarczyć im minimum informacji na temat stron ASP, aby swobodnie mogli korzystać z tego narzędzia. Jednak aplikacja ASP może być dostosowywana na potrzeby wielu klientów, chcesz więc, aby mieli możliwość zrobienia tego we własnym zakresie. Jedynym sposobem na dokonanie tego jest stworzenie serii zmiennych konfiguracyjnych w zdarzeniu Application_OnStart. Pozwoli to twoim użytkownikom na centralną modyfikację możliwości programu. Weźmy na przykład:
Sub Application_OnStart
Application("DNS") = "OC"
Application("UserName") = "Admin"
Application("Password") = "yourpassword"
Application("AllowNew") = "Yes"
Application("AllowEnroll") = "Yes"
Application("Path2Logo") = "./images/logo.gif"
Application("AllowDrop") = "No"
Application("ChatMode") = "External"
End Sub
Ten kod pozwala na dostosowanie aplikacji ASP, będącej szkołą online. Po pierwsze użytkownicy określają nazwę DNS-a łączącego się z bazą danych szkoły:
Application("DNS") = "OC"
Mogą określić również użytkownika logującego się do bazy danych:
Application("UserName") = "Admin"
oraz hasło tego użytkownika:
Application("Password") = "yourpassword"
Następnie mogą kontrolować sposób funkcjonowania programu. Czy chcą udzielać dostępu nowym uczniom? Jeśli tak, należy umieścić następujący wiersz kodu:
Application("AllowNew") = "Yes"
Czy chcą, aby uczniowie mogli zapisać się na kurs? Jeśli tak, kod będzie taki:
Application("AllowEnroll") = "Yes"
Następnie klienci określają położenie ich logo firmowego:
Application("Path2Logo") = "./images/logo.gif"
Mogą określić, czy zezwolą na porzucenie kursu przez ucznia:
Application("AllowDrop") = "No"
Na końcu typ używanego programu do pogawędek:
Application("ChatMode") = "External"
W twojej dokumentacji mógłbyś podać użytkownikom stosowne instrukcje, traktujące o znaczeniu i wartościach tych zmiennych aplikacji. Wtedy mógłbyś w kodzie kontrolować opcje strony w oparciu o ich preferencje. Oto na przykład kod strony rekrutacji uczniów na kursy:
<%
Option Explicit
Dim conn
Dim RSCourses
if Application("AllowEnroll") = "Yes" then
set conn = server.createobject ("adodb.connection")
conn.open Application("DNS"), Application("UserName"), _
Application("Password")
set RSCourses = conn.execute ("SELECT CourseID, CourseName, " _
& CourseDescription FROM OCCourses")
%>
<P ALIGN="CENTER"><B><FONT COLOR="#0000A0" SIZE="+3"
FACE="Arial,Helvetica">Wybierz kurs</B></FONT>
<%
do until RSCourses.EOF
%>
<A HREF="../html/enrolldrop.asp?CourseID=
<% Response.Write RSCourses("CourseID") %>">
<IMG HEIGHT=52 WIDTH=56 SRC="../assets/images/p048.gif"
BORDER=0 ALT="Enroll" ></A>
<P><B><FONT FACE="Arial,Helvetica">
<% Response.Write RSCourses("CourseName") %> -
<% Response.Write RSCourses("CourseDescription") %></B></FONT>
<%
RSCourses.MoveNext
loop
end if
%>
Na wstępie stwierdzamy, że będziemy deklarować nasze zmienne:
Option Explicit
Następnie tworzymy zmienną, która będzie używana do połączenia z bazą danych:
Dim conn
oraz zmienną wyszukującą informacje o kursie:
Dim RSCourses
Tutaj sprawdzamy preferencje określone w zdarzeniu Application_OnStart aby się przekonać, czy w ogóle należy wyświetlić informacje dotyczące rekrutacji:
if Application("AllowEnroll") = "Yes" then
Jeśli wpisano wartość "Yes", wtedy powinniśmy wyświetlić te informacje. Możemy więc utworzyć obiekt połączenia:
set conn = server.createobject ("adodb.connection")
Zwróć uwagę na to, że zmienne aplikacji używane są do określenia DNS-a, nazwy użytkownika oraz hasła - danych potrzebnych do połączenia z bazą danych:
conn.open Application("DNS"), Application("UserName"), _
Application("Password")
Informacja o kursach jest wyszukiwana w bazie danych:
set RSCourses = conn.execute ("SELECT CourseID, CourseName, " _
& CourseDescription FROM OCCourses")
Zauważ, że ten HTML jest częścią instrukcji If. Nie będzie on wykonany, jeśli w zmiennej AllowEnroll znajdzie co innego niż "Yes"
<P ALIGN="CENTER"><B><FONT COLOR="#0000A0" SIZE="+3"
FACE="Arial,Helvetica">Wybierz kurs</B></FONT>
Następnie rozpoczynamy przechodzenie w pętli przez wszystkie kursy znajdujące się w bazie danych:
do until RSCourses.EOF
Każdy kurs wpisywany jest do przeglądarki jako łącze pozwalające gościowi zapisać się na wybrany z nich:
<A HREF="../html/enrolldrop.asp?CourseID=
<% Response.Write RSCourses("CourseID") %>">
<IMG HEIGHT=52 WIDTH=56 SRC="../assets/images/p048.gif"
BORDER=0 ALT="Enroll" ></A>
<P><B><FONT FACE="Arial,Helvetica">
<% Response.Write RSCourses("CourseName") %> -
<% Response.Write RSCourses("CourseDescription") %></B></FONT>
Następnie przechodzimy w pętli do przetwarzania następnego kursu:
RSCourses.MoveNext
loop
i kończymy blok If
end if
Jak stwierdzono wcześniej, aplikacja rozpoczyna swe działanie w chwili, gdy gość uzyskuje dostęp do jednej ze stron twojej witryny. Odpowiedni na ten moment kod tworzysz w obrębie zdarzenia Application_OnStart. Możesz również określić kod, który będzie uruchamiany przy zakończeniu działania aplikacji.
Aplikacja kończy swe działanie w chwili, gdy serwer jest wyłączany, możesz więc stworzyć kod zawiadomienia o porządkowaniu lub jakiegoś innego typu. Uważaj jednak na to, co umieszczasz w tym miejscu, ponieważ czasami twoja aplikacja zatrzyma się z powodu błędu lub problemu z serwerem. Jeśli tak się stanie, twój końcowy kod nigdy nie zostanie uruchomiony. Z tego powodu osobiście nie używam tego zdarzenia.
Zdarzenie ma następującą składnię:
Sub Application_OnEnd
'kod procedury
End Sub
Wiersz komentarza "kod procedury" możesz zastąpić dowolnym kodem uruchamianym w czasie wystąpienia tego zdarzenia.
Za każdym razem, gdy gość uzyskuje dostęp do twojej aplikacji ASP, uruchamiane jest zdarzenie Session_OnStart, a wtedy rozpocznie działanie dowolny kod umieszczony w tym zdarzeniu. Zdarzenie Session_OnStart następuje po zdarzeniu Application_OnStart, ale przed jakimkolwiek innym kodem strony ASP wywoływanej przez odwiedzającego.
Kiedy zdarzenie Session_OnStart zostanie uruchomione, wszystkie obiekty ASP stają się dla ciebie dostępne i możesz je wykorzystać w kodzie. Zdarzenie to ma następującą składnię:
Sub Session_OnStart
'kod procedury
End Sub
Zazwyczaj w tym miejscu umieszcza się kod inicjacji użytkownika, łączący w sobie takie rzeczy jak tworzenie rekordu w bazie danych na potrzeby sesji, uruchomienie koszyka na zakupy, ustawienie preferencji oraz tworzenie zmiennych i obiektów sesji wykorzystywanych w tym zdarzeniu.
Jednym z wielce użytecznych zastosowań zdarzenia Session_OnStart jest uniemożliwienie gościom wejścia na którąkolwiek ze stron twojej witryny, zanim nie wejdą na określoną przez ciebie stronę. Możesz na przykład wymagać od użytkowników przejścia przez twoją stronę główną, nim odwiedzą jakąkolwiek inną część twej witryny. Być może chcesz, aby logowali się tam przed przejściem dalej.
Poniżej zaprezentowano, w jak prosty sposób można tego dokonać przy użyciu zdarzenia Session_OnStart
Sub Session_OnStart
Response.Redirect "./welcome.asp"
End Sub
Pamiętaj, że zdarzenie Session_OnStart jest uruchamiane przed jakimkolwiek innym kodem stron aplikacji ASP, tak więc bez względu na to, jaką stronę ASP gość wpisze w przeglądarce, będą musieli najpierw odwiedzić stronę powitania.
Weź pod uwagę na prosty przykład użycia takiego kodu. Przykładowa witryna ma dwie strony: stronę powitania oraz jakąś inną. Kiedy goście wpiszą w przeglądarce adres innej strony, nie zobaczą jej. W zamian ujrzą stronę powitania ukazaną na rysunku 8.10. Goście nie mogą więc przejść wprost do jakiejś innej strony witryny. Muszą najpierw wejść na stronę powitania w celu zalogowania się lub po prostu w celu przejścia przez witrynę w sposób przez ciebie wymagany.
Rysunek 8.10. Powitalna strona próbnej witryny
Jeśliby jednak goście wpisaliby w przeglądarce adres innej strony, wtedy ujrzeliby ją, ponieważ ich sesja właśnie się rozpoczęła. Spójrz na rysunek 8.11.
Rysunek 8.11. Wygląd drugiej strony próbnej witryny
Sesja rozpoczyna się w momencie uzyskania przez gościa dostępu do pierwszej strony twojej aplikacji ASP. Kończy się natomiast, gdy wywołasz metodę Abandon lub gdy czas jej trwania upłynie z powodu braku kolejnego żądania dostępu do strony w wymaganej liczbie minut.
Kiedy sesja się skończy, uruchamiane jest zdarzenie Session_OnEnd, w którym możesz programowo wykorzystać obiekty Application Server i Session, ale obiekty Request i Response nie są w tym momencie dostępne. Zdarzenie ma następującą składnię:
Sub Session_OnEnd
'kod procedury
End Sub
W to zdarzenie możesz włączyć kod porządkowania. Możesz wpisać do bazy danych datę i godzinę zakończenia sesji gościa. Mógłbyś użyć również tego zdarzenia do zakończenia przetwarzania zadań, które stale pozostają otwarte lub do wysłania jakichś zawiadomień pocztą elektroniczną (jeśli jest to wymagane) przy użyciu obiektów CDO, które omówiono w następnym rozdziale.
Poniżej przedstawiono przykład tego, co można włączyć do zdarzenia Session_OnEnd. Ta procedura umieszcza nazwę komputera gościa w bazie danych, możesz więc rozpoznawać tożsamość gości twojej witryny. Wartość ta nie jest normalnie dostępna poprzez serwer IIS, ponieważ zwykle otrzymujesz jedynie adres IP gościa. Kod wykorzystuje niezależne narzędzie, które przeprowadza przeszukiwanie w tył adresu IP w celu określenia nazwy komputera. Gdyby kod ten nie był umieszczony w zdarzeniu Session_OnEnd, wystąpiłby problem związany ze zbyt długim czasem przetwarzania kodu i wstrzymaniem wyświetlenia żądanej strony w przeglądarce gościa. Teraz jednak, gdy kod ten znalazł się w zdarzeniu Session_OnEnd, odwiedzający nie muszą czekać na przetworzenie tego kodu:
Sub Session_OnEnd
Dim objDNS
Dim conn
Dim hostname
Dim GMT
set objDNS = server.createobject("INet.DNS.1")
objDNS.ip = request.servervariables("remote_addr")
If objDNS.Host <> "" Then
hostname = objDNS.Host
Else
hostname = request.servervariables("remote_addr")
End If
GMT = Cstr (dateadd("h", 6, now()))
set conn = server.createobject ("adodb.connection")
conn.open "IISLog", "sa", "yourpassword"
SQL = "update iislog..sessions set session_end = '" & GMT _
& "', hostname = '" & hostname & "'"
SQL = SQL & " where Session_id = " & cstr(Session("session_id"))
conn.Execute SQL
End Sub
Po pierwsze deklarowane są pewne zmienne, które będą używane w tym zdarzeniu. Jedna z nich będzie zapamiętywała kopię narzędzia przeszukiwania w tył DNS:
Dim objDNS
Następnie tworzona jest zmienna zapamiętująca połączenie z bazą danych:
Dim conn
Tworzona również jest zmienna przechowująca nazwę komputera gościa:
Dim hostname
oraz zmienna przechowująca czas Greenwich (GMT):
Dim GMT
Wykorzystywany jest obiekt Server do stworzenia kopii narzędzia przeszukiwania w tył:
set objDNS = server.createobject("INet.DNS.1")
Do właściwości IP tego obiektu wpisywany jest adres IP systemu gościa:
objDNS.ip = request.servervariables("remote_addr")
Do właściwości Host obiektu DNS jest teraz wpisywana nazwa komputera gościa. Jeśli jest to nazwa nieznana, ustawioną wartością będzie pusty ciąg:
If objDNS.Host <> "" Then
Jeśli nie, oznacza to, że nazwa komputera została odnaleziona:
hostname = objDNS.Host
W innym wypadku nazwa komputera nie została odnaleziona i wykorzystany będzie jedynie adres IP:
Else
hostname = request.servervariables("remote_addr")
End If
Chcemy również zapamiętać w bazie danych datę i godzinę zakończenia sesji odwiedzającego. Czas zapamiętywany jest w formacie GMT, który powstaje tutaj (USA) po dodaniu sześciu godzin do czasu strefy lokalnej, obowiązującego na serwerze:
GMT = Cstr (dateadd("h", 6, now()))
Następnie zestawiane jest połączenie z bazą danych:
set conn = server.createobject ("adodb.connection")
conn.open "IISLog", "sa", "yourpassword"
(Użyty tutaj obiekt Connection zostanie szczegółowo omówiony w rozdziale 14).
Instrukcja SQL zbudowana jest przy użyciu nazwy komputera oraz czasu zakończenia sesji. Te wartości będą wprowadzone do rekordu bazy danych korespondującego z numerem identyfikacyjnym sesji gościa (Session_ID
SQL = "update iislog..sessions set session_end = '" & GMT _
& "', hostname = '" & hostname & "'"
SQL = SQL & " where Session_id = " & cstr(Session("session_id"))
Ta instrukcja SQL jest następnie wykonywana w celu modyfikacji bazy danych:
conn.Execute SQL
Jak mogliśmy się przekonać z treści poprzednich podrozdziałów poświęconych obiektom Application i Session, na tych poziomach obiekty możemy tworzyć poprzez znaczniki Object w pliku global.asa. Te obiekty są udostępniane w kodzie przez zbiór StaticObjects zarówno obiektu Application, jak i Session
Wspomniane znaczniki umieszczone są poza znacznikami Script w pliku global.asa i mają następujący format:
<OBJECT RUNAT=Server SCOPE=TheScope ID=Name PRODIG="App.Class">
</OBJECT>
Tekst TheScope należy zastąpić słowem Session, gdybyś chciał stworzyć obiekt poziomu sesji lub słowem Application, gdybyś tworzył obiekt poziomu aplikacji. Tekst Name należy zamienić na nazwę obiektu, do której będziesz się odwoływał w kodzie. Zamiast ciągu App.Class w deklaracji musi znaleźć się nazwa serwera oraz klasa, którą chcesz utworzyć.
Na przykład poniżej tworzymy obiekt poziomu aplikacji o nazwie Aconn, który będzie obiektem połączenia z bazą danych ADO:
<OBJECT RUNAT=Server SCOPE=Application ID=Aconn PRODIG="adodb.
connection">
</OBJECT>
A tutaj tworzymy obiekt poziomu sesji o nazwie SobjMail o klasie NewMail obiektu CDO:
<OBJECT RUNAT=Server SCOPE=Session ID=SobjMail PRODIG="CDONTS.NewMail">
</OBJECT>
Materiał omówiony w tym rozdziale naprawdę przedstawia ASP jako technologię, dzięki której możliwe będzie tworzenie całościowych rozwiązań na potrzeby twojego firmowego Internetu bądź intranetu. Bez obiektów Application i Session twoja witryna byłaby niczym więcej, jak tylko serią stron, od przypadku do przypadku łączących się ze sobą. Jednak dzięki tym obiektom możesz tworzyć prawdziwe aplikacje w pełnym tego słowa znaczeniu.
Weź pod uwagę stronę e-commerce. Rysunek 8.12. przedstawia prawdziwą stronę, którą administruję. Strona pokazana na rysunku jest częścią kreatora zamówień. Zapytuje ona gości o konieczne szczegóły na temat zamawianego produktu. Strona w dużym stopniu bazuje na obiekcie Session w celu śledzenia poczynań gości tak, aby w ich koszyku znalazły się właściwe produkty, jak to widać w kodzie tej strony:
if isempty(Session("SessionID")) then
CurrentDateTime = Now
conn.Execute "insert into WICustomers (SessionDateTime) values ('"_
& CurrentDateTime & "')"
set RSSession = conn.Execute("select SessionID from WICustomers "_
& "where SessionDateTime = '" & CurrentDateTime & "'") Session("SessionID") = RSSession("SessionID")
end if
set RSTotal = conn.Execute("select Sum(TotalPrice) as TheTotal from
WIOrderItems "_
& "where SessionID = " & Session("SessionID"))
if RSTotal("TheTotal") * Application("ShipPercent") > Application
("MinShip") then
TopShipping = RSTotal("TheTotal") * Application("ShipPercent")
else
TopShipping = Application("MinShip")
end if
Response.Redirect "https://www.netstats2000.com/bud/html/"_
& shopping_cart.asp?SessionID=" & Session(SessionID")
W pierwszej części kodu sprawdzamy, czy zmienna sesji o nazwie SessionID jest pusta:
if isempty(Session("SessionID")) then
Jeśli zmienna sesji jest pusta oznacza to, że gość umieścił w koszyku swój pierwszy wybrany produkt i należy stworzyć dla niego odpowiedni rekord. Aktualna data i godzina systemowa będzie częścią rekordu koszyka:
CurrentDateTime = Now
Rekord jest dodawany do bazy danych:
conn.Execute "insert into WICustomers (SessionDateTime) values ('"_
& CurrentDateTime & "')"
Numer identyfikacyjny nowo utworzonego rekordu koszyka jest wyszukiwany w bazie danych:
set RSSession = conn.Execute("select SessionID from WICustomers "_
& "where SessionDateTime = '" & CurrentDateTime & "'")
W zmiennej sesji SessionID ustawiana jest wartość z rekordu koszyka:
Session("SessionID") = RSSession("SessionID")
Następna część kodu oblicza koszty wysyłki zamówionych produktów. Po pierwsze obliczany jest całkowity koszt zamówienia na bazie wyszukanych kosztów poszczególnych produktów w koszyku znajdujących się w zmiennej SessionID
set RSTotal = conn.Execute("select Sum(TotalPrice) as TheTotal from
WIOrderItems "_
& "where SessionID = " & Session("SessionID"))
Następnie zmienne aplikacji wykorzystywane są do porównania kosztu wysyłki z minimalną wartością tego kosztu:
if RSTotal("TheTotal") * Application("ShipPercent") > Application
("MinShip") then
Jeśli procentowa wartość kosztu wysyłki jest większa od dwóch, wykorzystujemy ją:
TopShipping = RSTotal("TheTotal") * Application("ShipPercent")
W innym wypadku używamy minimalnego kosztu wysyłki:
TopShipping = Application("MinShip")
Widzisz więc, że dobrze rozplanowana, złożona aplikacja ASP w pełni wykorzystuje funkcje obiektów Application i Session
Rysunek 8.12. Kreator zamówień
|