Wykład 8
Sposób działania ASP.NET
Skany:
ASP.NET 2.0 Projektowanie aplikacji internetowych, Randy Connolly, Helion, Prentice Hall 2008
ASP.NET to elementy biblioteki klas .NET Framework.
ASP.NET to klasy służące do budowy aplikacji dostępnych przez przeglądarkę WWW.
ASP.NET to platforma pozwalająca budować dynamiczne aplikacjie internetowe.
Strona ASP.NET to zwykły plik tekstowy z rozszerzeniem .aspx
W tym pliku są informacje dwojakiego rodzaju: treść przesyłana do przeglądarki, dane wykorzystywane przez środowisko ASP.NET na serwerze. „Siła” ASP.NET wynika z możliwości środowiska ASP.NET na serwerze.
Model zdarzeń ASP.NET
Model programowania w ASP.NET oparty jest na zdarzeniach. To jest jedna z najistotniejszych cech tego środowiska.
Budujemy (definujemy) metody, będące procedurami obsługi zdarzeń np.: Page_Load, TextBox1_TextChanged, Buton1_Click, DropDownList1_SelectedIndexChanged itp. Te metody (procedury obsługi zdarzeń) określają akcje, które mają być wykonane w momencie wystąpienia odpowiedniego zdarzenia: załadowania strony, zmiany tekstu w kontrolce “TextBox”, naciśnięcia przycisku “Button”, zmianie wyboru w kontrolce “ DropDownList” itd.
Po wykryciu zdarzenia, wykonywana jest procedura obsługi tego zdarzenia.
Zdarzenie może być obsługiwane przez wiele procedur obsługi. Te procedury mogą być dynamicznie zmieniane, i dynamicznie przydzielane.
W środowisku Visual Studio programista pisze (uzupełnia…) metody (procedury) obsługi zdarzeń.
Procedura obsługi zdarzenia to „akcja”, która ma być wykonana po wykryciu zajściu danego zdarzenia.
W .NET Framework wszystkie procedury obsługi zdarzeń (w języku C#) zwracają typ void.
Pobierają (mają) dwa parametry: parametr object i parametr EventArgs.
Zamiast parametru EventArgs może być parametr klasy dziedziczącej (pochodnej): CommandEventArgs, ImageClickEventArgs, …
Parametr object zawiera referencję obiektu, który wygenerował zdarzenie.
Jeżeli ta sama procedura obsługi zdarzeń jest wykorzystywana w wielu kontrolkach, to parametr object pozwala ustalić, która kontrolka wygenerowała dane zdarzenie.
Parametr EventArgs zawiera informacje specyficzne dla danego zdarzenia.
System zdarzeń w ASP.NET działa następująco: zdarzenie jest generowane na kliencie (w przeglądarce), następnie jest przesyłane do serwera i tam obsługiwane.
W aplikacjach Windows, systemie zdarzeń JavaScript, API (Application Programming Interface) np AJAX (Asynchronous JavaScript and XML) zdarzenia są generowane i obsługiwane po stronie klienta.
W związku z koniecznością komunikowania się z serwerem w technologii ASP.NET zestaw zdarzeń jest mały. Zdarzenia często występujące np. typu ruch myszy, nie są obsługiwane w ASP.NET. Mogą być obsługiwane po stronie klienta przez JavaScrip, Ajax …
Przesyłanie danych (postback)
Jedną z najważniejszych cech systemu zdarzeń jest przesyłanie zwrotne danych - postback.
W ASP.NET przesyłanie danych (zwrotne przesyłanie danych) to proces wysyłania danych przez przeglądarkę do samej siebie poprzez serwer.
Dane są przesłane na serwer z jednoczesnym żądaniem pobrania przeglądanej strony.
Przesłanie danych może wystąpić tylko na formularzach WWW (elementach „form” z atrybutem „runat=server”).
Tylko kontrolki serwera mogą generować przesłanie danych.
Cykl przetwarzania formularza WWW
(uproszczony cykl przesyłania danych)
Zdarzenia strony i kontrolek
W ASP.NET występują dwa rodzaje zdarzeń: zdarzenia strony i zdarzenia kontrolek.
Przesłanie żądania strony powoduje, że określona seria zdarzeń strony wyzwalana jest w określonej kolejności.
Zdarzenia kontrolek generowane są w ustalonych przypadkach i są skojarzone z określonymi kontrolkami. Część zdarzeń jest wspólna dla wszystkich kontrolek, część jest specyficzna.
Stan widoku, stan kontrolki
Protokół http jest bezstanowy, serwer po odpowiedzeniu na żądanie strony „zapomina” - nie przechowuje stanu strony.
Aplikacje internetowe często wymagają przechowywania stanu formularza między kolejnymi wywołaniami strony.
Np. chcemy przechowywać wpisy dokonane w formularzu pomiędzy kolejnymi przesłaniami na serwer.
Stan widoku to jedna z najważniejszych funkcji ASP.NET.
Jest to specjalnie zakodowany ciąg znaków wykorzystywany do przechowywania informacji o stronie i formularzu między kolejnymi żądaniami.
Wszystkie elementy, które nie są przesyłane za pomocą standardowego mechanizmu przesyłania (HTML POST) są zapisywane w tym ciągu znaków, w ten sposób zapamiętywany jest stan (danych) formularza WWW i przesyłany jest do przeglądarki. Gdy formularz odsyłany jest na serwer, to odsyłany jest wraz z zapisanym stanem widoku. Na serwerze odczytywany jest stan widoku (ponieważ jest zapisany w elemencie formularza). Odtwarzane są stany kontrolek sprzed wysłania. ASP.NET aktualizuje stan kontrolek, korzystając z przesłanych danych, następnie wywołuje standardowe procedury obsługi zdarzeń strony i kontrolek.
Stan widoku jest generowany po wykonaniu kodu strony, przed utworzeniem odpowiedzi
Stan widoku generowany jest po wykonaniu kodu strony, przed utworzeniem odpowiedzi. Wartość każdej kontrolki serwera WWW jest serializowana na postać tekstową postaci nazwa-wartość. Ciąg stanu widoku wysyłany jest do przeglądarki jako ukryty element <input> o nazwie „_VIEWSTATE”.
Gdy klient prześle formularz WWW do serwera:
ASP.NET odczytuje stan widoku z elementu <input> formularza,
deserializuje dane, odtwarza stan wszystkich kontrolek sprzed wysłania,
aktualizuje stan kontrolek,
korzysta z przesłanych danych,
wywołuje standardowe procedury obsługi zdarzeń strony i kontrolek.
Jeżeli chcemy wyłączyć stan widoku dla strony musimy umieścić wpis:
<%@ Page … … EnableViewState=”false” %>
Po wpisaniu tej dyrektywy strona nie będzie przesyłała sama do siebie informacji.
Przyczyną wyłączenia stanu widoku dla strony może być np. duży zbiór danych do przesłania (baza danych) lub ograniczenia w przesyłaniu danych (urządzenia mobilne).
Stan kontrolek pozwala na przechowywanie własnych danych kontrolki pomiędzy przesłaniami strony (podobnie jak stan widoku). Stanu kontrolek nie można wyłączyć programowo.
Cykl życia strony
Zdarzenia strony i kontrolek wywoływane są w określonej kolejności, ta kolejność to cykl życia strony.
Poniższy rysunek pokazuje ten cykl.
W uproszczony sposób możemy opisać cykl życia strony dzieląc go między pięć kroków.
Inicjalizacja strony
Wykrycie czy jest to nowe żądanie, czy przesłanie danych, inicjalizacja strony, kontrolek, wywołanie procedury obsługi zdarzeń strony: Page_PreInit, Page_Init, wywołanie metod PreInit, Init kontrolek serwera, stosowanie tematów.
Ładowanie
Jeżeli żądanie strony nastąpiło w wyniku przesłania danych, to do właściwości kontrolek pobierane są właściwości ze stanu strony i stanu kontrolek.
Obsługa zdarzeń przesłania danych
Jeżeli żądanie strony nastąpiło w wyniku przesłania danych, to wywoływane są procedury obsługi zdarzeń przesłania danych.
Generowanie danych
Generowanie danych dla strony, zapisywanie stanu widoku, stanu kontrolek. Kontrolki wraz ze znacznikami przesyłane są do wyjściowego strumienia odpowiedzi. Wywoływane są metody PreRender, Render kontrolek i strony. Wygenerowany wynik odsyłany jest do klienta w postaci HTTP.
Wyładowanie
Wykonywane są operacje czyszczące, zwalniające zasoby. Wywoływane są metody Unload.
Na każdym etapie cyklu strona ASP.NET generuje zdarzenia. Ich obsługa powinna być zawarta w kodzie strony.
Jeżeli włączona jest opcja „AutoEventWireup” to ustalona jest konwencja nazw procedur.
Np. dwuklik w kontrolkę „Button1” tworzy procedurę „Button1_Click”
protected void Button1_Click(object sender, EventArgs e)
{ … }
oraz wiąże ją ze zdarzeniem „Click”:
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" />
Wykrywanie przesyłania danych
Czasami musimy odróżnić pierwsze przesłanie strony od kolejnych. Np. przy odczycie danych z bazy danych. W kolejnych przesłaniach dane pobierane są z widoku strony. Czy to jest przesłanie strony w wyniku żądania „PostBack” możemy sprawdzić przez sprawdzenie wartości właściwości „PostBack”. Przy pierwszym załadowaniu strony możemy np. inaczej postąpić niż przy przesyłaniu danych:
protected void Page_Load(object sender, EventArgs e)
{…
if (!IsPostBack) {……}
…}
Kontrolki wysyłające i nie wysyłające danych
Zdarzenie „Click” kontrolki od razu wywołuje operację przesłania danych - np. „Button”.
Są zdarzenie, które generują przesłanie danych, ale nie robią tego od razu po wygenerowaniu np. „SelectedIndexChanged”. Jeśli chcemy by przesłanie danych nastąpiło od razu musimy ustawić własność kontrolki
AutoPostBack="True"
Są również kontrolki, które nie powodują przesłania danych np. „Label”.
Przesyłanie pomiędzy stronami
Dotychczas opisany mechanizm dotyczył przesyłania danych z danego formularza z powrotem do tego samego formularza. Czasami jest potrzeba przesłania danych z jednego formularza (strony) na drugi formularz (drugą stronę).
Przesłanie danych wykonujemy przy użyciu właściwości PostBackUrl. Określamy tu adres strony która będzie obsługiwała przesłanie. Np.,.:
<asp:Button ID=”Button1” Text=”Zapisz” runat=”server” PostBackUrl= "~/druga.aspx" />
Na stronie druga.aspx nie odpowiadamy na zdarzenie Click.
Obsługa tego zdarzenia musi nastąpić w metodzie Page_Load.
Będąc na stronie druga.aspx, musimy uzyskać dostęp do kontrolki z poprzedniej strony default.aspx.
Klasa Page ma własność PreviousPage odwołującą się do obiektu Page reprezentującego poprzedni formularz WWW.
Opiszmy taki przypadek.
Na stronie default.aspx jest:
TextBox1 do którego wpisujemy nazwisko;
Button1 (opisany powyżej)
Na stronie druga.aspx jest label2.
Po kliknięciu w Button1 na stronie default.aspx, chcemy przenieść się na stronę druga.aspx i chcemy by w Label2 pojawiło się nazwisko wpisane w TextBox1 ze strony default.aspx.
Możemy to zrealizować np. tak na stronie druga.aspx:
protected void Page_Load(object sender, EventArgs e)
{
TextBox txtName = (TextBox)PreviousPage.FindControl("TextBox1");
Label2.Text = txtName.Text;
}
Kompilacja kodu ASP.NET
Co się dzieje, gdy nastąpi żądanie pobrania strony ASP.NET?
Nazwijmy ją „HelloWorld.aspx”.
Wersja uproszczona
Żądanie pobrania strony.
Elementy wizualne są przekształcane na klasy.
Te klasy wraz z kodem są dynamicznie kompilowane do postaci MSIL.
Za pomocą JIT kod jest konwertowany na kod natywny procesora i wykonywany na serwerze.
Wygenerowany jest kod HTML i JavaScript
Wygenerowany kod przesłany jest do przeglądarki.
Wersja rozbudowana
W ASP.NET używana jest konstrukcja klasy częściowej (partial class) pozwalająca na definicję klasy rozbitą na kilka plików łączonych w czasie kompilacji w momencie żądania pobrania strony.
Wszystkie formularze dziedziczą po klasie „Page” zdefiniowanej w przestrzeni nazw „System.Web.UI”
Klasa „Page” dziedziczy po klasie „TemplateControl” a ta dziedziczy po klasie „Control”.
Klasa „Page” dziedziczy właściwości i metody po tych klasach.
Kolejność kompilacji
ASP.NET kompiluje pliki aplikacji w ustalonej kolejności.
Pliki nazywane plikami wyższego poziomu kompilowane są w pierwszej kolejności.
Pliki wyższego poziomu to w kolejności pliki zawarte w katalogach: App_GlobalResources, App_WebResources, plik Web.config, App_Code, plik Global.asax.
Pliki niższego poziomu kompilowane są w miarę potrzeby w ustalonej kolejności: App_LocalResources, procedury obsługi HTTP (pojedyncze formularze .aspx, kontrolki użytkownika .ascx, procedury usług sieci .asmx …)
Klasa Page
Wszystkie formularze WWW dziedziczą po klasie Page, zdefiniowanej w przestrzeni nazw System.Web.UI. Oznacza to, że każda strona może korzystać z własności i metod klasy Page.
Będziemy to wykorzystywać.
Cykl życia aplikacji ASP.NET
Strona ASP.NET jest przekształcana na postać klasy, kompilowana, wykonywana.
Wykonywanie wiąże się z wykonaniem cyklu życia strony.
Końcowym etapem cyklu życia strony jest przesłanie wygenerowanego kodu HTML do przeglądarki.
Cykl życia strony jest jednym z kilku procesów przetwarzania realizujących cykl życia aplikacji ASP.NET.
1. Użytkownik żąda przesłania zasobu ASP.NET z serwera
Cykl życia aplikacji zaczyna się w momencie wysłania przez przeglądarkę żądania zasobu pochodzącego z aplikacji ASP.NET na serwerze WWW.
Na serwerze WWW może być wiele rozmaitych zasobów różnych typów.
{Musi to być serwer obsługujący ASP.NET np. IIS (Internet Information Services).}
Na serwerze IIS działa rozszerzenie i filtr ISAPI (Internet Serwer Application Programming Interface) będące bibliotekami DLL (Dynamic-Link Library) dla Windows.
Gdy IIS dostanie żądanie, określa które rozszerzenie ISAPI będzie obsługiwało żądanie.
Żądania statyczne takie jak HTML obsługiwane są bezpośrednio przez IIS.
Jeżeli na serwerze jest zainstalowany .NET Framework rozszerzenia .aspx, .asmx, .ascx … kojarzone są z biblioteką „aspnet_isapi.dll”.
Model obsługi żądania zależy od modelu IIS.
W IIS 6 sam program IIS nie obsługuje żadnych żądań ISAPI. Żądania są wysyłane do ogólnego programu roboczego o nazwie w3wp.exe, tworzonego osobno dla każdej aplikacji ASP.NET. program w3wp.exe obsługuje rozszerzenie aspnet_isapi.dll.
Każda aplikacja WWW w modelu IIS 6 jest izolowana od innych aplikacji.
Proces roboczy przekazuje żądania do łańcucha klas .NET, w których jest kontynuowany proces przetwarzania żądania.
2. Utworzenie domeny aplikacji przy pierwszym żądaniu dowolnego zasobu z aplikacji
Jeden serwer obsługuje może obsługiwać wiele aplikacji internetowych.
Aplikacja internetowa zainstalowana jest w katalogu głównym lub katalogu wirtualnym serwera.
Gdy serwer otrzyma pierwsze żądanie zasobu ASP.NET dla danej aplikacji internetowej tworzona jest za pomocą klasy ApplicationManager, klasa aplikacji AppDomain - domena aplikacji.
Każda aplikacja ma własną klasę AppDomain co zapewnia izolację pamięci dla każdej aplikacji, każda też ma własne środowisko uruchomieniowe.
Po utworzeniu domeny AppDomain tworzony jest w nim obiekt klasy HttpRuntime, a następnie wywoływana jest jego metoda ProcessRequest.
3. Kompilowanie elementów wyższego poziomu w razie potrzeby
Elementy wyższego poziomu kompilowane są w pierwszej kolejności. Jeśli dotychczas nie zostały skompilowane to są teraz kompilowane. Kompilowane są również jeśli nastąpiła zmiana w elemencie najwyższego poziomu.
4. Tworzenie podstawowych obiektów ASP.NET dla obsługiwanego żądania
Po wywołaniu metody ProcessRequest obiektu HttpRuntime środowisko ASP.NET tworzy podstawowe obiekty pozwalające na przetwarzanie żądania w środowisku ASP.NET.
HttpContext reprezentuje kontekst bieżącego zadania, tworzy podstawowe obiekty i zapewnia do nich dostęp.
Te obiekty to między innymi:
HttpRequest - zawiera wszystkie informacje dotyczące bieżącego zadania (typ przeglądarki, pliki cookies dla danej witryny dostępne na kliencie, parametry GET, POST wysyłane do serwera.
HttpResponse - zawiera wszystkie informacje dotyczące odpowiedzi wysyłanej przez ASP.NET do przeglądarki: kod HTML, JavaScript, cookies …
5. Przypisywanie obiektu HttpApplication do żądania
Po utworzeniu podstawowych obiektów obiekt HttpRuntime pobiera obiekt aplikacji realizujący żądanie. Obiekt ten to instancja klasy HttpApplication.
Jeśli istnieje plik Global.asax to on może zdefiniować obiekt tworzony zamiast HttpApplication.
Każdy obiekt AppDomian, poprzez obiekt HttpApplicationFactory, może mieć pulę obiektów HttpApplication składającą się z więcej niż jednego obiektu.
Obiekt klasy HttpApplication w czasie swojego istnienia może przetworzyć wiele żądań, jednorazowo jednak przetwarza tylko jedno żądanie.
Wielkość puli obiektów HttpApplication zależy od obciążenia aplikacji.
W czasie inicjalizacji obiektu HttpApplication wszystkie moduły http skojarzone z aplikacją są tworzone i umieszczane w tym obiekcie.
Moduł HTTP to obiekt wykorzystywany do obsłużenia żądania aplikacji.
Moduły są wywoływane w ramach potoku obsługi żądań HttpApplication.
Moduły są napisane w kodzie zarządzanym.
Moduły analizują przychodzące żądania, wykonują działania zależne od żądania.
Przykłady modułów: OutputCacheModule, SessionStateModule, WindowsAuthenticationModule…
6. Przetwarzanie żądania z użyciem potoku HttpApplication
Po zainicjowaniu i pobraniu obiektu HttpApplication następuje przetwarzanie żądania.
Żądanie jest przetwarzane w określonej, zdefiniowanej kolejności i dlatego nazywane jest potokiem.
Potok żądania składa się głównie z generowanych zdarzeń obsługiwanych przez HttpApplication, moduły http, zdefiniowane procedury obsługi HTTP dla danego typu pliku.
W potoku wykonywane są między innymi następujące operacje: kontrola poprawności żądania, wygenerowanie zdarzenia BeginRequest, wygenerowanie zdarzenia AuthenticationRequest, wygenerowanie zdarzenia PostAuthenticationRequest, ……
Wykład 8 (2a).doc Aplikacje internetowe
P. Zaremba 11/11